@devioarts/capacitor-mdns 0.0.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +110 -0
- package/DevioartsCapacitorMdns.podspec +3 -3
- package/Package.swift +1 -1
- package/README.md +272 -101
- package/android/build.gradle +3 -9
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/devioarts/capacitor/mdns/AndroidNsdBackend.kt +145 -0
- package/android/src/main/java/com/devioarts/capacitor/mdns/MdnsOptions.kt +32 -0
- package/android/src/main/java/com/devioarts/capacitor/mdns/MdnsValidation.kt +26 -0
- package/android/src/main/java/com/devioarts/capacitor/mdns/NsdBackend.kt +59 -0
- package/android/src/main/java/com/devioarts/capacitor/mdns/mDNS.kt +496 -175
- package/android/src/main/java/com/devioarts/capacitor/mdns/mDNSPlugin.kt +85 -49
- package/dist/docs.json +313 -15
- package/dist/esm/definitions.d.ts +89 -16
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.js +22 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +8 -1
- package/dist/esm/web.js +35 -3
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +57 -4
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +57 -4
- package/dist/plugin.js.map +1 -1
- package/docs/electron.md +91 -0
- package/docs/platform-setup.md +58 -0
- package/docs/playground.md +50 -0
- package/docs/runtime-behavior.md +80 -0
- package/electron/dist/plugin-settings.js +22 -0
- package/electron/dist/plugin-settings.js.map +1 -0
- package/electron/dist/plugin.cjs.js +774 -0
- package/electron/dist/plugin.cjs.js.map +1 -0
- package/electron/global.d.ts +2 -0
- package/electron/mdns-bridge.cjs +33 -4
- package/electron/mdns.ts +628 -107
- package/electron/rollup.config.mjs +22 -0
- package/electron/src/index.ts +2 -0
- package/electron/src/plugin-settings.ts +19 -0
- package/electron/tsconfig.json +21 -0
- package/electron/types-public/index.d.ts +47 -0
- package/ios/Sources/mDNSPlugin/mDNS.swift +481 -124
- package/ios/Sources/mDNSPlugin/mDNSPlugin.swift +85 -23
- package/ios/Tests/mDNSPluginTests/BridgeTests.swift +46 -0
- package/ios/Tests/mDNSPluginTests/MDNSTests.swift +490 -0
- package/package.json +55 -20
- package/ios/Tests/mDNSPluginTests/mDNSPluginTests.swift +0 -15
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.2.0] - 2026-11-07
|
|
4
|
+
|
|
5
|
+
### Upgrade from 0.1.0
|
|
6
|
+
|
|
7
|
+
- Existing method signatures and result shapes are retained. Continuous discovery is additive,
|
|
8
|
+
but validation, failure reporting and overlapping discovery behavior have changed as noted below.
|
|
9
|
+
- iOS now declares a minimum deployment target of 15.0. Capacitor dependencies are restricted to
|
|
10
|
+
version 8; applications using another major version are not supported.
|
|
11
|
+
- Service types, instance names, TXT records and timeouts are validated more strictly. Previously
|
|
12
|
+
tolerated invalid inputs can now return `error: true`.
|
|
13
|
+
- A valid new `discover()` cancels the previous request with an error. On iOS, discovery without
|
|
14
|
+
a name filter now waits for the complete timeout. Check `error` before consuming results;
|
|
15
|
+
errors discard partial results, and a failed stop can return `publishing: true`.
|
|
16
|
+
- Electron applications must install `bonjour-service@~1.4.0` and rerun `npx cap-electron sync`.
|
|
17
|
+
Manual IPC integrations using a custom renderer origin must configure `trustedOrigins`.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Continuous multi-type discovery on iOS, Android and Electron through `watchServices()` and
|
|
22
|
+
`stopWatching()`, with `serviceFound`, `serviceLost` and `watchError` listeners. Valid replacement
|
|
23
|
+
calls stop previous watchers; stopping leaves advertisements and one-shot discovery independent.
|
|
24
|
+
Thanks to [Idrimi](https://github.com/Idrimi) for the original feature in
|
|
25
|
+
[PR #7](https://github.com/devioarts/capacitor-mdns/pull/7).
|
|
26
|
+
- Full found/lost snapshots, duplicate-type normalization, stale-callback guards, native resolve
|
|
27
|
+
retries, shared Android resolver scheduling and multicast locks, and Electron TTL expiry / IPC events.
|
|
28
|
+
- Resolved Android NSD TXT attributes, optional service hostnames, playground live service lists / errors / TXT publication and
|
|
29
|
+
regression tests for watcher lifecycle and both Electron integration routes.
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- CocoaPods source tags now use the repository's `v` prefix. npm archives include this changelog.
|
|
34
|
+
- Electron: a failed response to an incoming Bonjour query no longer permanently blocks later
|
|
35
|
+
publication, discovery or watches. Fatal transport errors still stop affected operations.
|
|
36
|
+
- Electron: name conflicts fail when the probe detects them, and stopping an unpublished service
|
|
37
|
+
no longer sends goodbye records for another publisher's name. Missing generated registration
|
|
38
|
+
reports the required `npx cap-electron sync` step.
|
|
39
|
+
- Electron: goodbye is preserved if an announcement has started but its send callback is still pending;
|
|
40
|
+
stopped services cannot reannounce after a late callback. Duplicate discovered addresses are removed.
|
|
41
|
+
- The supported `bonjour-service` range is limited to `~1.4.0` pending verification of probe cleanup
|
|
42
|
+
behavior in later minor versions; package, playground and installation instructions use the same range.
|
|
43
|
+
- Discovered addresses prefer IPv4 on all platforms while preserving native IPv6 scope suffixes.
|
|
44
|
+
Added regressions for packet failures, Bonjour teardown, address ordering, native bridge input
|
|
45
|
+
validation and Android recovery after a late unregistration confirmation.
|
|
46
|
+
|
|
47
|
+
- Android: NSD callbacks (delivered on NsdManager's internal thread) are now marshalled to the main thread before touching any state, removing data races between discovery results, the timeout, and publish completion. A publish confirmation racing the publish timeout can no longer complete the call twice.
|
|
48
|
+
- Android: before API 34 only one `resolveService` may be active, so concurrent resolves were silently dropped and services lost. Resolves are now queued, retried on `FAILURE_ALREADY_ACTIVE`, and individually timed out.
|
|
49
|
+
- Android: stopping, replacing or timing out a pending registration cancels it immediately through its listener, allowing subsequent publication. Late callbacks cannot resurrect a cancelled service. `close()` fails pending discovery.
|
|
50
|
+
- iOS: discovery waits for the entire requested timeout unless a named target resolves with an IP address, retaining late peers even after a failed or filtered resolve.
|
|
51
|
+
- iOS: the `NWBrowser` duplicate check used un-normalized type/domain, so every browse update spawned new resolvers for already known services.
|
|
52
|
+
- iOS: a denied Local Network permission is now reported as an error instead of an empty discovery result.
|
|
53
|
+
- All platforms validate service types, UTF-8 instance/TXT lengths and string-only TXT before stopping an active advertisement. Android now publishes TXT as well.
|
|
54
|
+
|
|
55
|
+
- Electron: a malformed service type (e.g. `http`, `_http._xyz.`) is now rejected with an error instead of being silently advertised/browsed as `_http._tcp.`, matching iOS and Android. An invalid type no longer stops a broadcast that is already running.
|
|
56
|
+
- All platforms reject invalid timeouts, clamp valid delays and use the same default broadcast name. A new valid `discover()` replaces its predecessor; errors return empty results. Dots and hyphens compare equally in name filters.
|
|
57
|
+
- Electron: transport errors fail pending publication, name conflicts are reported explicitly, and discovery handles late address records. Destroy ends pending discoveries and late callbacks cannot mutate completed results.
|
|
58
|
+
- Electron: manual IPC checks trusted top-level senders and event recipients.
|
|
59
|
+
- npm archives exclude local audit files while retaining SwiftPM tests. Android declares coroutines directly and lint failures block builds. iOS requires version 15, matching Capacitor 8.
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
|
|
63
|
+
- `bonjour-service` is declared as an optional peer dependency (needed by Electron apps only).
|
|
64
|
+
- Electron: `new mDNS(bonjour?, options?)` accepts an injectable Bonjour implementation and timeouts for tests.
|
|
65
|
+
- Android: NSD access moved behind an internal `NsdBackend` seam (`AndroidNsdBackend` in production) so the logic is unit-testable on the JVM.
|
|
66
|
+
- iOS: `MDNS` exposes internal factories and timers for tests.
|
|
67
|
+
- Removed the unused disabled Dependabot template and Android instrumentation placeholder. Playground lint uses the installed flat React configuration and ignores generated native projects.
|
|
68
|
+
|
|
69
|
+
### Tests
|
|
70
|
+
|
|
71
|
+
- Added deterministic Electron regressions for validation, publication/stop failures, replacement, late addresses, TTL expiry, IPC trust and bridge subscriptions, plus real network discovery tests.
|
|
72
|
+
- Added JVM and iOS simulator regressions for callbacks, timeouts, replacement, UTF-8 validation, resolver scheduling, watcher cleanup and stale events. Removed template placeholder tests.
|
|
73
|
+
|
|
74
|
+
## [0.1.0]
|
|
75
|
+
|
|
76
|
+
Compared with `v0.0.3`.
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
|
|
80
|
+
- Added `getPluginPlatform()` to the public API, returning `ios`, `android`, `electron`, or `web` from the implementation that handled the call.
|
|
81
|
+
- Added Capacitor Electron package exports, public Electron type declarations, plugin metadata for `devioarts/capacitor-electron`, and a dedicated Electron build step.
|
|
82
|
+
- Added Electron IPC support for `getPluginPlatform()` and kept the manual preload bridge available through `electron/mdns-bridge.cjs`.
|
|
83
|
+
- Added an in-repository playground app that exercises broadcast, discovery, Electron bridge usage, logging, and runtime platform detection.
|
|
84
|
+
- Added focused docs for platform setup, Electron setup, playground usage, and runtime behavior.
|
|
85
|
+
- Added Electron end-to-end tests for publish/discover/stop behavior, platform detection, invalid input handling, and overlapping broadcast calls.
|
|
86
|
+
- Added GitHub issue templates, pull request template, CI workflow, a disabled Dependabot template, and funding metadata.
|
|
87
|
+
|
|
88
|
+
### Changed
|
|
89
|
+
|
|
90
|
+
- `startBroadcast()` on iOS, Android, and Electron is now guarded by a publish timeout so native/runtime callbacks cannot leave the JavaScript promise pending forever.
|
|
91
|
+
- Starting a new advertisement now stops or replaces the previous active advertisement; the plugin keeps only one active broadcast at a time.
|
|
92
|
+
- Discovery sessions are now timeboxed and clean up native listeners, browsers, service-info callbacks, and resolvers more reliably.
|
|
93
|
+
- Overlapping discovery calls are serialized or safely isolated from stale callbacks, depending on platform behavior.
|
|
94
|
+
- Service type and name inputs are trimmed and normalized consistently across supported platforms.
|
|
95
|
+
- Port validation now requires values in the `1..65535` range.
|
|
96
|
+
- Android now declares `INTERNET` and `CHANGE_WIFI_MULTICAST_STATE` permissions in the plugin manifest for merge during `npx cap sync`.
|
|
97
|
+
- Package exports now expose the root plugin, Electron runtime entry points, Electron settings, the manual bridge, and `package.json`.
|
|
98
|
+
- Build, clean, lint, and test scripts now include the Electron runtime and e2e test pipeline.
|
|
99
|
+
- README setup and API documentation were regenerated and reorganized around the maintained in-repo playground and docs.
|
|
100
|
+
|
|
101
|
+
### Fixed
|
|
102
|
+
|
|
103
|
+
- Fixed web fallback behavior so unsupported browser calls return shaped errors instead of success-like results.
|
|
104
|
+
- Fixed pending publish promises when iOS or Android publishing is stopped, replaced, fails, or times out.
|
|
105
|
+
- Fixed Android discovery cleanup and listener handling to avoid old callbacks completing a newer request.
|
|
106
|
+
- Fixed Android discovery failure reporting so start failures surface through the documented error shape.
|
|
107
|
+
- Fixed iOS discovery session handling so stale NWBrowser, NetServiceBrowser, or resolver callbacks cannot complete a newer request.
|
|
108
|
+
- Fixed iOS discovery failures to return an error result instead of silently completing as a clean empty search.
|
|
109
|
+
- Fixed TXT record normalization on iOS and Electron so discovered values are returned as strings.
|
|
110
|
+
- Fixed Electron broadcast stop/destroy handling to avoid orphaned Bonjour advertisers.
|
|
@@ -9,9 +9,9 @@ Pod::Spec.new do |s|
|
|
|
9
9
|
s.license = package['license']
|
|
10
10
|
s.homepage = package['repository']['url']
|
|
11
11
|
s.author = package['author']
|
|
12
|
-
s.source = { :git => package['repository']['url'], :tag => s.version
|
|
12
|
+
s.source = { :git => package['repository']['url'], :tag => "v#{s.version}" }
|
|
13
13
|
s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
|
-
s.ios.deployment_target = '
|
|
15
|
-
s.dependency 'Capacitor'
|
|
14
|
+
s.ios.deployment_target = '15.0'
|
|
15
|
+
s.dependency 'Capacitor', '~> 8.0'
|
|
16
16
|
s.swift_version = '5.1'
|
|
17
17
|
end
|
package/Package.swift
CHANGED
package/README.md
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# @devioarts/capacitor-mdns
|
|
2
2
|
|
|
3
|
-
mDNS plugin for Capacitor that supports Bonjour/mDNS advertisements and discovery
|
|
3
|
+
mDNS plugin for Capacitor that supports Bonjour/mDNS advertisements and discovery on iOS,
|
|
4
|
+
Android, Electron, and a safe web fallback.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
**Supported Capacitor version: v8. iOS 15 or later is required.**
|
|
7
|
+
|
|
8
|
+
#### Supported platforms: ✓ iOS ✓ Android ✓ Electron ✓ Web fallback
|
|
9
|
+
|
|
10
|
+
The in-repository [`playground`](./playground) is the example app used during development.
|
|
7
11
|
|
|
8
12
|
## Install
|
|
9
13
|
|
|
@@ -12,85 +16,88 @@ npm install @devioarts/capacitor-mdns
|
|
|
12
16
|
npx cap sync
|
|
13
17
|
```
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
```xml
|
|
18
|
-
<uses-permission android:name="android.permission.INTERNET" />
|
|
19
|
-
```
|
|
19
|
+
For Electron, also install `bonjour-service@~1.4.0` and run `npx cap-electron sync`.
|
|
20
|
+
See the [Electron setup](./docs/electron.md) for details.
|
|
20
21
|
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<array>
|
|
33
|
-
<string>_http._tcp</string>
|
|
34
|
-
</array>
|
|
35
|
-
```
|
|
22
|
+
## Upgrading from 0.1.0
|
|
23
|
+
|
|
24
|
+
Version 0.2.0 retains the existing method signatures and result shapes and adds continuous
|
|
25
|
+
discovery. It also tightens input validation, changes overlapping discovery and error handling,
|
|
26
|
+
and raises the declared iOS minimum to 15.0. Review the
|
|
27
|
+
[upgrade notes](./CHANGELOG.md#020---2026-11-07) before updating an existing application.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { mDNS } from '@devioarts/capacitor-mdns';
|
|
36
33
|
|
|
37
|
-
|
|
38
|
-
## ElectronJS
|
|
34
|
+
const runtime = await mDNS.getPluginPlatform();
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
await mDNS.startBroadcast({ type: '_http._tcp.', name: 'MyService', port: 9100 });
|
|
37
|
+
const result = await mDNS.discover({ type: '_http._tcp.', timeout: 3000 });
|
|
38
|
+
await mDNS.stopBroadcast();
|
|
42
39
|
```
|
|
43
40
|
|
|
44
|
-
|
|
45
|
-
> base, if you run electron differently, you may need to adjust the code.
|
|
41
|
+
## Continuous discovery
|
|
46
42
|
|
|
47
|
-
|
|
43
|
+
Thank you, [Idrimi](https://github.com/Idrimi), for contributing the original continuous discovery
|
|
44
|
+
feature in [PR #7](https://github.com/devioarts/capacitor-mdns/pull/7).
|
|
48
45
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
app.whenReady().then(() => {
|
|
56
|
-
//...
|
|
57
|
-
mdns.init();
|
|
58
|
-
//...
|
|
46
|
+
`watchServices()` monitors multiple service types on iOS, Android and Electron until stopped.
|
|
47
|
+
Register listeners before starting; a new valid call replaces the previous watch.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
const found = await mDNS.addListener('serviceFound', ({ service }) => {
|
|
51
|
+
console.log('Found', service.name, service.hosts, service.port);
|
|
59
52
|
});
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// ...
|
|
63
|
-
mdns.init();
|
|
64
|
-
// ...
|
|
53
|
+
const lost = await mDNS.addListener('serviceLost', ({ service }) => {
|
|
54
|
+
console.log('Lost', service.name, service.hosts, service.port);
|
|
65
55
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
```javascript
|
|
77
|
-
//...
|
|
78
|
-
// THIS IS IMPORTANT FOR PLUGIN!
|
|
79
|
-
const {createMDNSAPI} = require("@devioarts/capacitor-mdns/electron/mdns-bridge.cjs");
|
|
80
|
-
//...
|
|
81
|
-
// THIS IS IMPORTANT FOR PLUGIN!
|
|
82
|
-
contextBridge.exposeInMainWorld('mDNS', createMDNSAPI({ ipcRenderer }));
|
|
83
|
-
contextBridge.exposeInMainWorld('mdns', createMDNSAPI({ ipcRenderer })) // alias
|
|
56
|
+
const errors = await mDNS.addListener('watchError', (event) => {
|
|
57
|
+
console.error(event.type, event.errorMessage, event.watching);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const result = await mDNS.watchServices({
|
|
61
|
+
types: ['_http._tcp.', '_airplay._tcp.', '_googlecast._tcp.'],
|
|
62
|
+
});
|
|
63
|
+
// Later, including when leaving the screen:
|
|
64
|
+
await mDNS.stopWatching();
|
|
65
|
+
await Promise.all([found.remove(), lost.remove(), errors.remove()]);
|
|
84
66
|
```
|
|
85
67
|
|
|
86
|
-
|
|
68
|
+
Found/lost events contain the full service snapshot; `hosts` is always an array. A service
|
|
69
|
+
that disappears before resolving emits neither event. Browser errors stop watching and emit
|
|
70
|
+
`watchError` with `watching: false`; exhausted resolution retries emit it with `watching: true`.
|
|
71
|
+
`stopWatching()` leaves broadcasting and one-shot discovery running. Browsers do not support mDNS.
|
|
72
|
+
|
|
73
|
+
## Platform Setup
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
Android requires mDNS/network permissions in `AndroidManifest.xml`; the plugin also declares them
|
|
77
|
+
so they are merged during sync. iOS requires local network keys in `Info.plist`.
|
|
78
|
+
Electron support is intended for [`devioarts/capacitor-electron`](https://github.com/devioarts/capacitor-electron)
|
|
79
|
+
and uses metadata exported from `@devioarts/capacitor-mdns/electron/settings`.
|
|
80
|
+
|
|
81
|
+
Detailed setup lives in:
|
|
82
|
+
|
|
83
|
+
- [iOS and Android setup](./docs/platform-setup.md)
|
|
84
|
+
- [Electron setup](./docs/electron.md)
|
|
85
|
+
- [Playground](./docs/playground.md)
|
|
86
|
+
- [Runtime behavior](./docs/runtime-behavior.md)
|
|
87
|
+
|
|
87
88
|
## API
|
|
88
89
|
|
|
89
90
|
<docgen-index>
|
|
90
91
|
|
|
92
|
+
* [`getPluginPlatform()`](#getpluginplatform)
|
|
91
93
|
* [`startBroadcast(...)`](#startbroadcast)
|
|
92
94
|
* [`stopBroadcast()`](#stopbroadcast)
|
|
93
95
|
* [`discover(...)`](#discover)
|
|
96
|
+
* [`watchServices(...)`](#watchservices)
|
|
97
|
+
* [`stopWatching()`](#stopwatching)
|
|
98
|
+
* [`addListener('serviceFound' | 'serviceLost', ...)`](#addlistenerservicefound--servicelost-)
|
|
99
|
+
* [`addListener('watchError', ...)`](#addlistenerwatcherror-)
|
|
100
|
+
* [`removeAllListeners()`](#removealllisteners)
|
|
94
101
|
* [Interfaces](#interfaces)
|
|
95
102
|
* [Type Aliases](#type-aliases)
|
|
96
103
|
|
|
@@ -101,6 +108,19 @@ contextBridge.exposeInMainWorld('mdns', createMDNSAPI({ ipcRenderer })) // alias
|
|
|
101
108
|
|
|
102
109
|
Public API surface of the Capacitor mDNS plugin.
|
|
103
110
|
|
|
111
|
+
### getPluginPlatform()
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
getPluginPlatform() => Promise<MdnsPluginPlatformResult>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Return the platform implementation currently serving plugin calls.
|
|
118
|
+
|
|
119
|
+
**Returns:** <code>Promise<<a href="#mdnspluginplatformresult">MdnsPluginPlatformResult</a>></code>
|
|
120
|
+
|
|
121
|
+
--------------------
|
|
122
|
+
|
|
123
|
+
|
|
104
124
|
### startBroadcast(...)
|
|
105
125
|
|
|
106
126
|
```typescript
|
|
@@ -148,33 +168,118 @@ Discover services of a given type and optionally filter by instance name.
|
|
|
148
168
|
--------------------
|
|
149
169
|
|
|
150
170
|
|
|
171
|
+
### watchServices(...)
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
watchServices(options: MdnsWatchOptions) => Promise<MdnsWatchResult>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Continuously watch several service types. A valid call replaces the previous watch.
|
|
178
|
+
Register listeners before starting. Each resolved service emits `serviceFound` once;
|
|
179
|
+
disappearance emits `serviceLost` with its last snapshot. No loss is emitted for an
|
|
180
|
+
unresolved service. Watching and one-shot discovery can run together.
|
|
181
|
+
Thanks to Idrimi for contributing the original continuous discovery feature (PR #7).
|
|
182
|
+
|
|
183
|
+
| Param | Type |
|
|
184
|
+
| ------------- | ------------------------------------------------------------- |
|
|
185
|
+
| **`options`** | <code><a href="#mdnswatchoptions">MdnsWatchOptions</a></code> |
|
|
186
|
+
|
|
187
|
+
**Returns:** <code>Promise<<a href="#mdnswatchresult">MdnsWatchResult</a>></code>
|
|
188
|
+
|
|
189
|
+
--------------------
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
### stopWatching()
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
stopWatching() => Promise<MdnsWatchStopResult>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Stop all watchers. No events from that watch are emitted after this resolves.
|
|
199
|
+
|
|
200
|
+
**Returns:** <code>Promise<<a href="#mdnswatchstopresult">MdnsWatchStopResult</a>></code>
|
|
201
|
+
|
|
202
|
+
--------------------
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
### addListener('serviceFound' | 'serviceLost', ...)
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
addListener(eventName: 'serviceFound' | 'serviceLost', handler: (event: MdnsServiceEvent) => void) => Promise<PluginListenerHandle>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
| Param | Type |
|
|
212
|
+
| --------------- | --------------------------------------------------------------------------------- |
|
|
213
|
+
| **`eventName`** | <code>'serviceFound' \| 'serviceLost'</code> |
|
|
214
|
+
| **`handler`** | <code>(event: <a href="#mdnsserviceevent">MdnsServiceEvent</a>) => void</code> |
|
|
215
|
+
|
|
216
|
+
**Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>
|
|
217
|
+
|
|
218
|
+
--------------------
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
### addListener('watchError', ...)
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
addListener(eventName: 'watchError', handler: (event: MdnsWatchErrorEvent) => void) => Promise<PluginListenerHandle>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
| Param | Type |
|
|
228
|
+
| --------------- | --------------------------------------------------------------------------------------- |
|
|
229
|
+
| **`eventName`** | <code>'watchError'</code> |
|
|
230
|
+
| **`handler`** | <code>(event: <a href="#mdnswatcherrorevent">MdnsWatchErrorEvent</a>) => void</code> |
|
|
231
|
+
|
|
232
|
+
**Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>
|
|
233
|
+
|
|
234
|
+
--------------------
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
### removeAllListeners()
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
removeAllListeners() => Promise<void>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
--------------------
|
|
244
|
+
|
|
245
|
+
|
|
151
246
|
### Interfaces
|
|
152
247
|
|
|
153
248
|
|
|
249
|
+
#### MdnsPluginPlatformResult
|
|
250
|
+
|
|
251
|
+
Result of getPluginPlatform(). Useful for validating that calls are routed
|
|
252
|
+
through the expected platform bridge.
|
|
253
|
+
|
|
254
|
+
| Prop | Type | Description |
|
|
255
|
+
| -------------- | ----------------------------------------------------------------- | -------------------------------------------------- |
|
|
256
|
+
| **`platform`** | <code><a href="#mdnspluginplatform">MdnsPluginPlatform</a></code> | Platform implementation that produced this result. |
|
|
257
|
+
|
|
258
|
+
|
|
154
259
|
#### MdnsBroadcastResult
|
|
155
260
|
|
|
156
261
|
Result of startBroadcast(). Indicates whether advertising is active
|
|
157
262
|
and the final service name. On failure, `error` is true and `errorMessage`
|
|
158
263
|
describes the issue.
|
|
159
264
|
|
|
160
|
-
| Prop | Type | Description
|
|
161
|
-
| ------------------ | --------------------------- |
|
|
162
|
-
| **`error`** | <code>boolean</code> | True if the operation failed.
|
|
163
|
-
| **`errorMessage`** | <code>string \| null</code> | Error description or null on success.
|
|
164
|
-
| **`name`** | <code>string</code> | Final (possibly uniquified) service instance name. Empty on failure.
|
|
165
|
-
| **`publishing`** | <code>boolean</code> | Whether
|
|
265
|
+
| Prop | Type | Description |
|
|
266
|
+
| ------------------ | --------------------------- | ----------------------------------------------------------------------------- |
|
|
267
|
+
| **`error`** | <code>boolean</code> | True if the operation failed. |
|
|
268
|
+
| **`errorMessage`** | <code>string \| null</code> | Error description or null on success. |
|
|
269
|
+
| **`name`** | <code>string</code> | Final (possibly uniquified) service instance name. Empty on failure. |
|
|
270
|
+
| **`publishing`** | <code>boolean</code> | Whether an advertiser is active, or may still be active after failed cleanup. |
|
|
166
271
|
|
|
167
272
|
|
|
168
273
|
#### MdnsBroadcastOptions
|
|
169
274
|
|
|
170
275
|
Options for starting a Bonjour/mDNS advertisement.
|
|
171
276
|
|
|
172
|
-
| Prop | Type | Description
|
|
173
|
-
| ---------- | ------------------------------------------- |
|
|
174
|
-
| **`type`** | <code>string</code> | Service type (including the trailing dot).
|
|
175
|
-
| **`name`** | <code>string</code> | Service instance name.
|
|
176
|
-
| **`port`** | <code>number</code> | TCP port to advertise.
|
|
177
|
-
| **`txt`** | <code><a href="#mdnstxt">MdnsTxt</a></code> | Optional TXT key–value pairs (UTF-8 strings).
|
|
277
|
+
| Prop | Type | Description |
|
|
278
|
+
| ---------- | ------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
279
|
+
| **`type`** | <code>string</code> | Service type (including the trailing dot). |
|
|
280
|
+
| **`name`** | <code>string</code> | Service instance name (maximum 63 UTF-8 bytes). Defaults to `DevIOArtsMDNS`. |
|
|
281
|
+
| **`port`** | <code>number</code> | TCP port to advertise. |
|
|
282
|
+
| **`txt`** | <code><a href="#mdnstxt">MdnsTxt</a></code> | Optional TXT key–value pairs (UTF-8 strings). |
|
|
178
283
|
|
|
179
284
|
|
|
180
285
|
#### MdnsStopResult
|
|
@@ -182,23 +287,23 @@ Options for starting a Bonjour/mDNS advertisement.
|
|
|
182
287
|
Result of stopBroadcast(). Indicates whether the advertiser is active
|
|
183
288
|
after the call (normally false) and includes error information.
|
|
184
289
|
|
|
185
|
-
| Prop | Type | Description
|
|
186
|
-
| ------------------ | --------------------------- |
|
|
187
|
-
| **`error`** | <code>boolean</code> | True if an error occurred while stopping.
|
|
188
|
-
| **`errorMessage`** | <code>string \| null</code> | Error description or null on success.
|
|
189
|
-
| **`publishing`** | <code>boolean</code> |
|
|
290
|
+
| Prop | Type | Description |
|
|
291
|
+
| ------------------ | --------------------------- | --------------------------------------------------------------------------------------------- |
|
|
292
|
+
| **`error`** | <code>boolean</code> | True if an error occurred while stopping. |
|
|
293
|
+
| **`errorMessage`** | <code>string \| null</code> | Error description or null on success. |
|
|
294
|
+
| **`publishing`** | <code>boolean</code> | False after confirmed stop; true when stopping failed and the advertiser may still be active. |
|
|
190
295
|
|
|
191
296
|
|
|
192
297
|
#### MdnsDiscoverResult
|
|
193
298
|
|
|
194
299
|
Result of discover(). Contains normalized services and error information.
|
|
195
300
|
|
|
196
|
-
| Prop | Type | Description
|
|
197
|
-
| ------------------- | --------------------------- |
|
|
198
|
-
| **`error`** | <code>boolean</code> | True if discovery encountered an error (partial results may still be present).
|
|
199
|
-
| **`errorMessage`** | <code>string \| null</code> | Error description or null when no error occurred.
|
|
200
|
-
| **`servicesFound`** | <code>number</code> | Convenience count equal to services.length.
|
|
201
|
-
| **`services`** | <code>MdnsService[]</code> |
|
|
301
|
+
| Prop | Type | Description |
|
|
302
|
+
| ------------------- | --------------------------- | ---------------------------------------------------------------------------------------- |
|
|
303
|
+
| **`error`** | <code>boolean</code> | True if discovery encountered an error (partial results may still be present). |
|
|
304
|
+
| **`errorMessage`** | <code>string \| null</code> | Error description or null when no error occurred. |
|
|
305
|
+
| **`servicesFound`** | <code>number</code> | Convenience count equal to services.length. |
|
|
306
|
+
| **`services`** | <code>MdnsService[]</code> | Resolved services with numeric addresses. Empty on error; partial results are discarded. |
|
|
202
307
|
|
|
203
308
|
|
|
204
309
|
#### MdnsService
|
|
@@ -206,31 +311,97 @@ Result of discover(). Contains normalized services and error information.
|
|
|
206
311
|
Normalized description of a discovered Bonjour/mDNS service.
|
|
207
312
|
Returned from {@link mDNSPlugin.discover}.
|
|
208
313
|
|
|
209
|
-
| Prop
|
|
210
|
-
|
|
|
211
|
-
| **`name`**
|
|
212
|
-
| **`type`**
|
|
213
|
-
| **`domain`**
|
|
214
|
-
| **`port`**
|
|
215
|
-
| **`hosts`**
|
|
216
|
-
| **`
|
|
314
|
+
| Prop | Type | Description |
|
|
315
|
+
| -------------- | ------------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
316
|
+
| **`name`** | <code>string</code> | Instance name of the service (may be uniqued by the OS, e.g. "My App (2)"). |
|
|
317
|
+
| **`type`** | <code>string</code> | Full service type including the trailing dot, e.g. `"_http._tcp."`. |
|
|
318
|
+
| **`domain`** | <code>string</code> | Service domain; typically `"local."`. |
|
|
319
|
+
| **`port`** | <code>number</code> | Port the service advertises. |
|
|
320
|
+
| **`hosts`** | <code>string[]</code> | Resolved numeric IP addresses, IPv4 first, then IPv6 with any available scope suffix. |
|
|
321
|
+
| **`hostname`** | <code>string</code> | Host name when supplied by the platform, e.g. `"my-device.local."`. |
|
|
322
|
+
| **`txt`** | <code><a href="#mdnstxt">MdnsTxt</a></code> | TXT dictionary (key → value). |
|
|
217
323
|
|
|
218
324
|
|
|
219
325
|
#### MdnsDiscoverOptions
|
|
220
326
|
|
|
221
327
|
Options for Bonjour/mDNS discovery.
|
|
222
328
|
|
|
223
|
-
| Prop | Type | Description
|
|
224
|
-
| ------------- | -------------------- |
|
|
225
|
-
| **`type`** | <code>string</code> | Service type (including the trailing dot).
|
|
226
|
-
| **`name`** | <code>string</code> | Optional instance name filter (prefix-safe).
|
|
227
|
-
| **`timeout`** | <code>number</code> | Discovery timeout in milliseconds.
|
|
228
|
-
| **`useNW`** | <code>boolean</code> | iOS-only hint to use `NWBrowser` instead of `NetServiceBrowser`.
|
|
329
|
+
| Prop | Type | Description |
|
|
330
|
+
| ------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
331
|
+
| **`type`** | <code>string</code> | Service type (including the trailing dot). |
|
|
332
|
+
| **`name`** | <code>string</code> | Optional instance name filter (prefix-safe). |
|
|
333
|
+
| **`timeout`** | <code>number</code> | Discovery timeout in milliseconds. Finite numbers only; fractions are truncated and the delay is clamped to 0–2147483647. |
|
|
334
|
+
| **`useNW`** | <code>boolean</code> | iOS-only hint to use `NWBrowser` instead of `NetServiceBrowser`. |
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
#### MdnsWatchResult
|
|
338
|
+
|
|
339
|
+
Native browsers have been requested; later failures are reported through `watchError`.
|
|
340
|
+
|
|
341
|
+
| Prop | Type |
|
|
342
|
+
| --------------------- | --------------------------- |
|
|
343
|
+
| **`error`** | <code>boolean</code> |
|
|
344
|
+
| **`errorMessage`** | <code>string \| null</code> |
|
|
345
|
+
| **`watchersStarted`** | <code>number</code> |
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
#### MdnsWatchOptions
|
|
349
|
+
|
|
350
|
+
Options for continuous discovery on iOS, Android and Electron.
|
|
351
|
+
|
|
352
|
+
| Prop | Type | Description |
|
|
353
|
+
| ----------- | --------------------- | ---------------------------------------------------------------------------------- |
|
|
354
|
+
| **`types`** | <code>string[]</code> | Nonempty list of service types. Trailing dots are optional; duplicates are merged. |
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
#### MdnsWatchStopResult
|
|
358
|
+
|
|
359
|
+
Stops watching independently of any active broadcast.
|
|
360
|
+
|
|
361
|
+
| Prop | Type |
|
|
362
|
+
| ------------------ | --------------------------- |
|
|
363
|
+
| **`error`** | <code>boolean</code> |
|
|
364
|
+
| **`errorMessage`** | <code>string \| null</code> |
|
|
365
|
+
| **`watching`** | <code>boolean</code> |
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
#### PluginListenerHandle
|
|
369
|
+
|
|
370
|
+
| Prop | Type |
|
|
371
|
+
| ------------ | ----------------------------------------- |
|
|
372
|
+
| **`remove`** | <code>() => Promise<void></code> |
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
#### MdnsServiceEvent
|
|
376
|
+
|
|
377
|
+
Both found and lost events contain a complete service snapshot, including `hosts`.
|
|
378
|
+
|
|
379
|
+
| Prop | Type |
|
|
380
|
+
| ------------- | --------------------------------------------------- |
|
|
381
|
+
| **`service`** | <code><a href="#mdnsservice">MdnsService</a></code> |
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
#### MdnsWatchErrorEvent
|
|
385
|
+
|
|
386
|
+
Browser failures stop the watch; exhausted service resolution retries leave it running.
|
|
387
|
+
|
|
388
|
+
| Prop | Type |
|
|
389
|
+
| ------------------ | -------------------- |
|
|
390
|
+
| **`type`** | <code>string</code> |
|
|
391
|
+
| **`errorMessage`** | <code>string</code> |
|
|
392
|
+
| **`watching`** | <code>boolean</code> |
|
|
229
393
|
|
|
230
394
|
|
|
231
395
|
### Type Aliases
|
|
232
396
|
|
|
233
397
|
|
|
398
|
+
#### MdnsPluginPlatform
|
|
399
|
+
|
|
400
|
+
Runtime implementation that handled a plugin call.
|
|
401
|
+
|
|
402
|
+
<code>'ios' | 'android' | 'electron' | 'web'</code>
|
|
403
|
+
|
|
404
|
+
|
|
234
405
|
#### MdnsTxt
|
|
235
406
|
|
|
236
407
|
Key–value map for TXT records of a Bonjour/mDNS service.
|
package/android/build.gradle
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
ext {
|
|
2
2
|
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
3
|
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
|
|
4
|
-
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
|
|
5
|
-
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
|
|
6
4
|
}
|
|
7
5
|
|
|
8
6
|
buildscript {
|
|
@@ -25,9 +23,6 @@ android {
|
|
|
25
23
|
defaultConfig {
|
|
26
24
|
minSdk = project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
|
|
27
25
|
targetSdk = project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
|
|
28
|
-
versionCode = 1
|
|
29
|
-
versionName = "1.0"
|
|
30
|
-
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
31
26
|
}
|
|
32
27
|
buildTypes {
|
|
33
28
|
release {
|
|
@@ -36,7 +31,7 @@ android {
|
|
|
36
31
|
}
|
|
37
32
|
}
|
|
38
33
|
lint {
|
|
39
|
-
abortOnError =
|
|
34
|
+
abortOnError = true
|
|
40
35
|
}
|
|
41
36
|
compileOptions {
|
|
42
37
|
sourceCompatibility JavaVersion.VERSION_21
|
|
@@ -55,10 +50,9 @@ repositories {
|
|
|
55
50
|
|
|
56
51
|
|
|
57
52
|
dependencies {
|
|
58
|
-
implementation
|
|
53
|
+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1"
|
|
59
54
|
implementation project(':capacitor-android')
|
|
60
55
|
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
61
56
|
testImplementation "junit:junit:$junitVersion"
|
|
62
|
-
|
|
63
|
-
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
57
|
+
testImplementation 'org.json:json:20250517'
|
|
64
58
|
}
|