native_mdns_scanner 1.1.0
native_mdns_scanner: ^1.1.0 copied to clipboard
Dart FFI bindings for macOS mDNS/Bonjour services. Provides native access to multicast DNS functionality on macOS.
native_mdns_scanner #
Dart FFI bindings for macOS mDNS/Bonjour services. This library provides native access to multicast DNS functionality on macOS through FFI bindings to Objective-C code.
Features #
- π Simple mDNS scanning - Discover devices by service type
- π― Simultaneous multi-service scanning - Scan multiple service types at once
- π Periodic scanning - Run queries at regular intervals
- β±οΈ Timing analysis - Analyze discovery patterns and performance
- π₯οΈ CLI tool - Command-line interface for quick testing
- π Rich device information - IP, port, TXT records, and discovery metadata
Platform Support #
- β macOS (arm64 + x86_64)
- β iOS (not tested)
- β Windows (not supported)
- β Linux (not supported)
Installation #
Add this to your pubspec.yaml:
dependencies:
native_mdns_scanner: ^1.0.0
Or install directly from GitHub:
dependencies:
native_mdns_scanner:
git:
url: https://github.com/changyy/ffi-mdns-macos-dart.git
Quick Start #
Basic Usage #
import 'package:native_mdns_scanner/native_mdns_scanner.dart';
void main() async {
final mdnsFfi = MdnsFfi();
try {
// Scan for Chromecast devices
mdnsFfi.startScan('_googlecast._tcp');
// Wait for 10 seconds
await Future.delayed(Duration(seconds: 10));
mdnsFfi.stopScan();
// Get results
final devices = mdnsFfi.foundDevices;
for (final device in devices) {
print('Found: ${device.name} at ${device.ip}:${device.port}');
}
} finally {
mdnsFfi.dispose();
}
}
Simultaneous Multi-Service Scanning #
final mdnsFfi = MdnsFfi();
try {
final devices = await mdnsFfi.scanMultipleServices([
'_googlecast._tcp', // Chromecast
'_airplay._tcp', // AirPlay
'_raop._tcp', // Remote Audio Output Protocol
], timeout: Duration(seconds: 15));
print('Found ${devices.length} devices');
// Group by service type
final devicesByType = mdnsFfi.getDevicesByServiceType();
for (final serviceType in devicesByType.keys) {
final typeDevices = devicesByType[serviceType]!;
print('$serviceType: ${typeDevices.length} devices');
}
} finally {
mdnsFfi.dispose();
}
Periodic Scanning #
final mdnsFfi = MdnsFfi();
try {
final devices = await mdnsFfi.scanMultipleServicesWithPeriodic([
'_googlecast._tcp',
],
timeout: Duration(seconds: 30), // Total scan time
queryInterval: Duration(seconds: 5), // Query every 5 seconds
);
// Analyze timing patterns
TimingAnalyzer.analyzeTimings(devices);
} finally {
mdnsFfi.dispose();
}
CLI Tool #
The package includes a command-line tool for quick testing and debugging:
# Install globally
dart pub global activate native_mdns_scanner
# Or run directly
dart run bin/mdns_cli.dart
CLI Examples #
# Simple scan
dart run bin/mdns_cli.dart scan _googlecast._tcp
# Scan multiple services
dart run bin/mdns_cli.dart multi _googlecast._tcp _airplay._tcp _raop._tcp
# Periodic scanning
dart run bin/mdns_cli.dart periodic _googlecast._tcp --interval 5 --duration 30
# Timing analysis
dart run bin/mdns_cli.dart timing _googlecast._tcp _airplay._tcp --timeout 20
CLI Options #
--timeout <seconds>: Scan timeout (default: 15)--interval <seconds>: Query interval for periodic scan (default: 5)--duration <seconds>: Total duration for periodic scan (default: 30)--help,-h: Show help message
Common Service Types #
| Service Type | Description | Example Devices |
|---|---|---|
_googlecast._tcp |
Google Cast | Chromecast, Google Home |
_airplay._tcp |
Apple AirPlay | Apple TV, AirPort Express |
_raop._tcp |
Remote Audio Output | AirPort Express, HomePod |
_http._tcp |
HTTP services | Web servers, cameras |
_ssh._tcp |
SSH servers | Raspberry Pi, servers |
_printer._tcp |
Network printers | HP, Canon printers |
_ipp._tcp |
Internet Printing | Modern network printers |
API Reference #
MdnsFfi Class #
The main class for mDNS operations.
Methods
startScan(String serviceType)- Start scanning for a service typestartPeriodicScan(String serviceType, {int queryIntervalMs, int totalDurationMs})- Start periodic scanningstopScan()- Stop all active scansscanMultipleServices(List<String> serviceTypes, {Duration timeout})- Scan multiple services simultaneouslyscanMultipleServicesWithPeriodic(List<String> serviceTypes, {Duration timeout, Duration queryInterval})- Periodic multi-service scanningisScanning()- Check if any scan is activefoundDevices- Get list of discovered devicesgetDevicesByServiceType()- Get devices grouped by service typedispose()- Clean up resources
DeviceInfo Class #
Represents a discovered mDNS service.
Properties
String name- Service nameString ip- IP addressint port- Port numberString serviceType- Service type (e.g., '_googlecast._tcp')Map<String, String> txtRecords- TXT record key-value pairsDateTime foundAt- Discovery timestampint queryNumber- Which query discovered this device
TimingAnalyzer Class #
Utility for analyzing discovery timing patterns.
Methods
static void analyzeTimings(List<DeviceInfo> devices)- Print detailed timing analysisstatic Map<String, dynamic> getStatistics(List<DeviceInfo> devices)- Get timing statisticsstatic String formatTime(DateTime time)- Format time as HH:mm:ss.SSS
Building from Source #
Prerequisites #
- macOS (for building the native library)
- Xcode command line tools
- Dart SDK 3.0+
Build Steps #
- Clone the repository:
git clone https://github.com/changyy/ffi-mdns-macos-dart.git
cd ffi-mdns-macos-dart
- Build the native library:
cd native
./build.sh
- Install Dart dependencies:
dart pub get
- Run examples:
dart run example/native_mdns_scanner_example.dart
dart run example/timing_test_example.dart
Project Structure #
ffi-mdns-macos-dart/
βββ lib/
β βββ native_mdns_scanner.dart # Main export
β βββ src/
β βββ mdns_bindings.dart # FFI bindings
β βββ device_info.dart # Device model
β βββ timing_analyzer.dart # Timing utilities
βββ native/
β βββ mdns_ffi.h # C header
β βββ mdns_ffi.m # Objective-C implementation
β βββ build.sh # Build script
β βββ libmdns_ffi.dylib # Compiled library
βββ example/
β βββ native_mdns_scanner_example.dart # Basic usage example
β βββ timing_test_example.dart # Timing analysis example
βββ bin/
β βββ mdns_cli.dart # CLI tool
βββ test/
βββ mdns_test.dart # Unit tests
Performance Notes #
- Simultaneous scanning: This library can scan multiple service types simultaneously, unlike many other mDNS libraries that scan sequentially
- Event processing: Uses a timer-based approach to process mDNS events efficiently
- Memory management: Properly manages native resources and prevents memory leaks
Troubleshooting #
Common Issues #
- Library not found: Make sure
libmdns_ffi.dylibis in thenative/directory - Permission denied: On macOS, you might need to allow network access in System Preferences
- No devices found: Some devices may not respond immediately; try increasing the timeout
Debug Mode #
Enable verbose logging by setting debug flags in your code:
// This will print detailed discovery information
final mdnsFfi = MdnsFfi();
// Logs are automatically printed to console
Contributing #
- Fork the repository
- Create your feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments #
- Built using Dart FFI for native interoperability
- Uses macOS Bonjour/mDNS APIs through Objective-C
- Inspired by the need for simultaneous multi-service mDNS scanning
Related Projects #
- multicast_dns - Pure Dart mDNS implementation
- bonsoir - Cross-platform service discovery
- nsd - Network Service Discovery plugin