Skip to main content

air_link_discovery 0.2.1 copy "air_link_discovery: ^0.2.1" to clipboard
air_link_discovery: ^0.2.1 copied to clipboard

Zero-config LAN device discovery using UDP broadcast for Air Link.

Air Link Discovery #

Zero-config LAN device discovery using UDP broadcast.

// Advertise this device
await DiscoveryService.advertise(name: 'My Phone', port: 8080);

// Discover other devices
DiscoveryService.discover().listen((peer) {
  print('Found: ${peer.name} @ ${peer.ip}:${peer.port}');
});

// Cleanup
await DiscoveryService.stopAll();

No configuration, no IP scanning, no manual setup. Devices on the same network find each other automatically.


Quick Start #

1. Add the dependency #

dependencies:
  air_link_discovery: ^0.2.0

2. Advertise your device #

import 'package:air_link_discovery/air_link_discovery.dart';

await DiscoveryService.advertise(port: 8080, name: 'My Device');

The device broadcasts its name and port every 2 seconds over UDP. Other devices running discover() will find it.

3. Discover peers #

DiscoveryService.discover().listen((peer) {
  print('${peer.name} at ${peer.ip}:${peer.port}');

  // Connect using Air Link Core
  final session = await Lan.connect(peer.ip, port: peer.port);
});

4. Stop when done #

await DiscoveryService.stopAll();

Instance API #

For running multiple discovery services independently (e.g., different apps on the same device):

final svc = DiscoveryService();

// Advertise
await svc.startAdvertise(name: 'Node A', port: 8081);

// Discover
svc.startDiscovery().listen((peer) {
  print('Found via instance: ${peer.name}');
});

// Cleanup
await svc.shutdown();

Self-filtering #

Each DiscoveryService instance generates a unique ID. By default, discovery() filters out advertisements from the same instance (filterSelf: true), so you never discover yourself.


API #

Static methods (backward compatible) #

Method Description
advertise({name, port, metadata, identityFingerprint, discoveryPort, interval}) Start advertising
discover({discoveryPort, filterSelf}) Start discovery, returns Stream<DiscoveredPeer>
stopAll() Stop all discovery activity
stopAdvertising() Stop advertising only
stopDiscovering() Stop discovering only

Instance methods #

Method Description
startAdvertise(...) Same as static advertise()
startDiscovery(...) Same as static discover()
stopAdvertise() Stop advertising
stopDiscovery() Stop discovering
shutdown() Stop all activity

Configuration #

Parameter Default Description
name Platform.localHostname Human-readable device name
port (required) The TCP port your server runs on
metadata {} Additional key-value pairs to advertise
identityFingerprint defaultFingerprint SHA-256 fingerprint of ECDSA identity key
discoveryPort 41234 UDP port for broadcast
interval 2 seconds How often to broadcast
filterSelf true Whether to filter own advertisements

Global defaults #

// Set once at app startup
DiscoveryService.defaultFingerprint = identity.fingerprint;

// All future adverts include it automatically
await DiscoveryService.advertise(port: 8080);

DiscoveredPeer #

Property Description
String name Device name
String ip IP address
int port TCP port
Map<String, String> metadata Advertised metadata
String? identityFingerprint ECDSA identity fingerprint (if provided)

Security #

Discovery sends plaintext UDP broadcasts. It is designed for discovery only — not for transmitting sensitive data.

  • Use identityFingerprint to verify the discovered peer matches the expected identity key when connecting via air_link_secure
  • The broadcast includes an instance ID for self-filtering, but the ID is not authenticated — any device on the network can send advertisements

Platform Support #

Platform Status
Android ✅ (requires INTERNET permission)
iOS ✅ (requires NSLocalNetworkUsageDescription)
macOS ✅
Windows ✅
Linux ✅

Resource Limits #

  • The dedup set (prevents duplicate peer emissions) is capped at 1000 entries
  • Old entries are automatically evicted on overflow

Module Integration #

// Discovery + Secure: find peers with verified identity
final fp = identity.fingerprint;
await DiscoveryService.advertise(port: 8080, identityFingerprint: fp);

DiscoveryService.discover().listen((peer) {
  if (peer.identityFingerprint != null) {
    // Connect securely — the fingerprint matches the expected key
    connectSecure(peer.ip, identity, port: peer.port);
  }
});
// Discovery + Core: simple connect
DiscoveryService.discover().listen((peer) async {
  final session = await Lan.connect(peer.ip, port: peer.port);
  await session.peer.sendText('Hi! Found you via discovery.');
});

Requirements #

  • Dart SDK >=3.0.0 <4.0.0
  • No external dependencies

License #

MIT

0
likes
160
points
48
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Zero-config LAN device discovery using UDP broadcast for Air Link.

Homepage
Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

air_link_core

More

Packages that depend on air_link_discovery