Depending on your project targets, you need at least :
NWBrowser.This plugin cannot be tested on an Android emulator (well it can, but the only services that you are able to discover are the ones broadcasted by your emulator).
In your Flutter project directory, run the following commands :
flutter pub add bonsoir
flutter pub getIf you want to use this plugin on iOS, you must update your deployment target to at least 13.0. To do so, open your iOS project in Xcode and select Runner, Targets → Runner and then the "General" tab. Under the "Minimum Deployments" section, update the iOS version to 13.0 or higher.
If you use Cocoapods, at the top of ios/Podfile, add the following :
platform :ios, '13.0'Finally, if you're building your app for iOS 14 or higher, you have to edit your Info.plist file.
Just add the following lines :
<key>NSLocalNetworkUsageDescription</key>
<string>Describe here why you want to use Bonsoir.</string>
<key>NSBonjourServices</key>
<array>
<string>_first-service._tcp</string>
<string>_second-service._tcp</string>
<string>_third-service._tcp</string>
<!-- Add more here -->
</array>Don't forget to edit them according to your needs.
If you want to use this plugin on macOS, you must update your deployment target to at least 10.15.
At the top of macos/Podfile, add the following :
platform :ios, '10.15'Also, open your macOS project in Xcode and select Runner, Targets → Runner and then the "General" tab. Under the "Minimum Deployments" section, update the macOS version to 10.15 or higher.
Avahi is typically preinstalled on Ubuntu and Fedora desktop systems, but it is not guaranteed. It is not installed by default on Arch Linux.
The installation instructions depend on your package manager and the distribution.
For Ubuntu / Debian-based distros (e.g., Linux Mint, PopOS) :
sudo apt install -y avahi-daemon avahi-discover avahi-utils libnss-mdns mdns-scanFor Fedora / RHEL / CentOS distros :
sudo dnf instal -y avahi avahi-tools nss-mdns mdns-scanFor Arch distros :
sudo pacman -S avahi nss-mdns mdns-scanUsually, no action is required in many Linux desktops but not guaranteed:
ufw is typically installed but inactive by default.firewalld is installed and active, and mDNS may already work due to the default port.If a firewall is active, and 5353/udp is blocked, it must be opened for mDNS :
sudo ufw allow 5353/udpsudo firewall-cmd --permanent --add-service=mdns and sudo firewall-cmd --reloadTo allow access to the Avahi system D-Bus service from inside the Flatpak sandbox, add these permissions to the manifest :
finish-args:
- --share=network
- --system-talk-name=org.freedesktop.AvahiThis still requires Avahi to be installed on the host OS.
Bonsoir has been made to be as easy to use as possible.
Here is how you can broadcast your service using Bonsoir :
// Let's create our service !
BonsoirService service = BonsoirService(
name: 'My wonderful service', // Put your service name here.
type: '_wonderful-service._tcp', // Put your service type here. Syntax : _ServiceType._TransportProtocolName. (see http://wiki.ros.org/zeroconf/Tutorials/Understanding%20Zeroconf%20Service%20Types).
port: 3030, // Put your service port here.
);
// And now we can broadcast it :
BonsoirBroadcast broadcast = BonsoirBroadcast(service: service);
await broadcast.initialize();
await broadcast.start();
// ...
// Then if you want to stop the broadcast :
await broadcast.stop();Here is how you can search for a broadcasted service :
// This is the type of service we're looking for :
String type = '_wonderful-service._tcp';
// Once defined, we can start the discovery :
BonsoirDiscovery discovery = BonsoirDiscovery(type: type);
await discovery.initialize();
// If you want to listen to the discovery :
discovery.eventStream!.listen((event) { // `eventStream` is not null as the discovery instance is "ready" !
switch (event) {
case BonsoirDiscoveryServiceFoundEvent():
print('Service found : ${event.service.toJson()}');
event.service!.resolve(discovery.serviceResolver); // Should be called when the user wants to connect to this service.
break;
case BonsoirDiscoveryServiceResolvedEvent():
print('Service resolved : ${event.service.toJson()}');
break;
case BonsoirDiscoveryServiceUpdatedEvent():
print('Service updated : ${event.service.toJson()}');
break;
case BonsoirDiscoveryServiceLostEvent():
print('Service lost : ${event.service.toJson()}');
break;
default:
print('Another event occurred : $event.');
break;
}
});
// Start the discovery **after** listening to discovery events :
await discovery.start();
// Then if you want to stop the discovery :
await discovery.stop();Discovery event cycles are platform-dependent. Bonsoir emits events as soon as the underlying platform reports them, so the frequency, ordering, and timing of these events may vary from one platform to another.
When a discovered service is resolved, BonsoirService.hostAddresses contains the network addresses exposed
by the platform, while BonsoirService.hostname contains the mDNS/SRV target hostname when the
platform provides one. You can check whether the current platform can populate this hostname field
by checking the BonsoirDiscovery.supportsMdnsHostname property. This does not guarantee that the
operating system can resolve .local hostnames natively for HTTP requests or sockets; use
hostAddresses when you need already-resolved network addresses.
If you're transitioning from multicast_dns, note that types don't end with .local
.
If you want a full
example, don't hesitate to check
this one on Github.
To run it :
melos bs.packages/bonsoir/example directory, and run flutter run.You have a lot of options to contribute to this project ! You can :
This plugin was initially created to use in my game, Mobile Werewolf. It is an unofficial mobile version of the famous board game Mafia / Werewolves. In this game, players can play against each others via Wi-Fi, so Bonsoir allows them to easily broadcast, discover and join local network parties.
The hand icon has been created by Vitaly Gorbachev.