@laravelka/zeroconf v1.0.0
@laravelka/zeroconf
Capacitor plugin for Zeroconf (mDNS) service discovery and broadcasting.
Install
npm install @laravelka/zeroconf
npx cap synciOS Setup
Prerequisites
- Xcode 15.0+
- CocoaPods
Configuration
- Open your project in Xcode:
npx cap open ios- Add the following keys to your
Info.plistfile:
<!-- Local Network Usage Description -->
<key>NSLocalNetworkUsageDescription</key>
<string>This app needs access to find and connect to local network devices</string>
<!-- Bonjour Services -->
<key>NSBonjourServices</key>
<array>
<string>_http._tcp.</string>
<!-- Add other service types your app will use -->
</array>Android Setup
Prerequisites
- Android Studio Electric Eel (2022.1.1) or newer
- Android SDK and Platform Tools installed
- Java 17 or newer
Configuration
- Open your project in Android Studio:
npx cap open android- Add the following permissions to your
android/app/src/main/AndroidManifest.xml:
<!-- Required permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />- Update your
android/variables.gradleto ensure compatibility:
ext {
minSdkVersion = 26
compileSdkVersion = 34
targetSdkVersion = 34
androidxActivityVersion = '1.7.0'
}- Make sure your
android/build.gradlehas the correct Java version:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
}Usage
import { ZeroConf } from '@laravelka/zeroconf';
import type { PluginListenerHandle, ZeroConfWatchResult } from '@laravelka/zeroconf';
let listener: PluginListenerHandle;
// Listen for service discovery events
const setupListeners = async () => {
listener = await ZeroConf.addListener('discover', (result: ZeroConfWatchResult) => {
console.log('Service discovered:', result);
// result.action will be 'added', 'removed', or 'resolved'
// result.service contains service information
});
};
// Register a service
await ZeroConf.register({
type: '_http._tcp.',
domain: 'local.',
name: 'MyService',
port: 3000,
txtRecord: {
path: '/api'
}
});
// Start watching for services
await ZeroConf.watch({
type: '_http._tcp.',
domain: 'local.'
});
// Cleanup listeners when done
await listener?.remove();
// Later: stop watching and cleanup
await ZeroConf.unwatch({
type: '_http._tcp.',
domain: 'local.'
});
await ZeroConf.unregister({
type: '_http._tcp.',
domain: 'local.',
name: 'MyService'
});
// Stop all discoveries and unregister all services
await ZeroConf.stop();
// Clean up resources when done
await ZeroConf.close();Configuration
Add the following to your capacitor.config.ts:
/// <reference types="@laravelka/zeroconf" />
import { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
plugins: {
ZeroConf: {
// Optional configuration options can be added here
}
}
};
export default config;API
addListener('discover', ...)getHostname()register(...)unregister(...)watch(...)unwatch(...)stop()close()- Interfaces
Main ZeroConf plugin interface.
addListener('discover', ...)
addListener(eventName: 'discover', listenerFunc: (result: ZeroConfWatchResult) => void) => Promise<PluginListenerHandle>Add a listener for service discovery events.
| Param | Type | Description |
|---|---|---|
eventName | 'discover' | - The name of the event to listen for |
listenerFunc | (result: ZeroConfWatchResult) => void | - Callback function that will be called when a service is discovered |
Returns: Promise<PluginListenerHandle>
Since: 1.0.0
getHostname()
getHostname() => Promise<{ hostname: string; }>Get the hostname of the device.
Returns: Promise<{ hostname: string; }>
Since: 1.0.0
register(...)
register(options: { type: string; domain?: string | undefined; name: string; port: number; txtRecord?: { [key: string]: string; } | undefined; }) => Promise<void>Register a new service.
| Param | Type | Description |
|---|---|---|
options | { type: string; domain?: string; name: string; port: number; txtRecord?: { key: string: string; }; } | - Service registration options |
Since: 1.0.0
unregister(...)
unregister(options: { type: string; name: string; }) => Promise<void>Unregister a previously registered service.
| Param | Type | Description |
|---|---|---|
options | { type: string; name: string; } | - Service unregistration options |
Since: 1.0.0
watch(...)
watch(options: { type: string; domain?: string; }) => Promise<void>Start watching for services of a specific type.
| Param | Type | Description |
|---|---|---|
options | { type: string; domain?: string; } | - Service watch options |
Since: 1.0.0
unwatch(...)
unwatch(options: { type: string; }) => Promise<void>Stop watching for services of a specific type.
| Param | Type | Description |
|---|---|---|
options | { type: string; } | - Service unwatch options |
Since: 1.0.0
stop()
stop() => Promise<void>Stop all ongoing service discoveries and unregister all services.
Since: 1.0.0
close()
close() => Promise<void>Close the Zeroconf instance and clean up resources.
Since: 1.0.0
Interfaces
PluginListenerHandle
| Prop | Type |
|---|---|
remove | () => Promise<void> |
ZeroConfWatchResult
Result of a ZeroConf service discovery event.
| Prop | Type |
|---|---|
action | 'added' | 'removed' | 'resolved' |
service | ZeroConfService |
ZeroConfService
Represents a discovered ZeroConf service.
| Prop | Type |
|---|---|
domain | string |
type | string |
name | string |
port | number |
hostname | string |
ipv4Addresses | string[] |
ipv6Addresses | string[] |
txtRecord | { key: string: string; } |
Example Usage
import { ZeroConf } from '@laravelka/zeroconf';
import type { PluginListenerHandle, ZeroConfWatchResult } from '@laravelka/zeroconf';
class ZeroConfExample {
private listener: PluginListenerHandle | null = null;
async initialize() {
// Setup event listener
this.listener = await ZeroConf.addListener('discover', (result: ZeroConfWatchResult) => {
console.log('Service discovered:', result);
// result.action will be 'added', 'removed', or 'resolved'
// result.service contains service information
});
// Register our service
await ZeroConf.register({
type: '_http._tcp.',
domain: 'local.',
name: 'MyService',
port: 3000,
txtRecord: {
path: '/api'
}
});
// Start watching for services
await ZeroConf.watch({
type: '_http._tcp.',
domain: 'local.'
});
}
async cleanup() {
// Remove event listener
if (this.listener) {
await this.listener.remove();
this.listener = null;
}
// Stop watching for services
await ZeroConf.unwatch({
type: '_http._tcp.',
domain: 'local.'
});
// Unregister our service
await ZeroConf.unregister({
type: '_http._tcp.',
domain: 'local.',
name: 'MyService'
});
// Stop all discoveries and unregister all services
await ZeroConf.stop();
// Clean up resources
await ZeroConf.close();
}
}Platform Support
- ✅ Android (using JmDNS)
- ✅ iOS (using Network.framework and NetService)
Requirements
- Capacitor 7.0.0 or newer
- iOS 13.0 or newer (Xcode 15.0+)
- Android API 26 (Android 8.0) or newer
License
MIT
9 months ago