nimrodda / flutter_nsd Goto Github PK
View Code? Open in Web Editor NEWA Flutter plugin that enables Network Service Discovery (mDNS) on various platforms via their native APIs.
License: Apache License 2.0
A Flutter plugin that enables Network Service Discovery (mDNS) on various platforms via their native APIs.
License: Apache License 2.0
There's two bugs in the plugin:
First, you should not reuse the resolve listener. See https://stackoverflow.com/questions/25815162/listener-already-in-use-service-discovery
Secondly, and this is more problematic, having discovered multiple services, even if resolve listener is not shared, only one of the discovered services will be resolved. See: https://stackoverflow.com/questions/24665342/nsdmanager-doesnt-resolve-multiple-discovered-services
This can be reproduced by creating a couple of services with the same service type,
e.g. in Macos dns-sd -R Foo _http._tcp . 8899 mydevice=1
and dns-sd -R Bar _http._tcp . 8899 mydevice=2
You can see that the problem goes away if you add some delay to before calling nsdManager?.resolveService
, but of course that wouldn't be a proper fix.
This is a critical bug, and I would be grateful for fixing it!
Hi,
I am trying to create a release build of a flutter project with flutter_nsd package
When I build this project for web (flutter build web) seems to be working.
On building for Windows (flutter build windows) I get an error:
used version of package:
flutter_nsd: ^1.4.0
flutter --version
Flutter 3.13.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision e1e47221e8 (28 hours ago) • 2023-08-22 21:43:18 -0700
Engine • revision b20183e040
Tools • Dart 3.1.0 • DevTools 2.25.0
flutter build windows
C:\temp\cnc-client\windows\flutter\ephemeral.plugin_symlinks\flutter_nsd\windows\flutter_nsd_plugin.cpp(104,92): error C2220: the following warning is treated as an error [C:\temp\cnc-client\build\windows\plugins\flutter_nsd\flutter_nsd_plugin.vcxproj]
C:\temp\cnc-client\windows\flutter\ephemeral.plugin_symlinks\flutter_nsd\windows\flutter_nsd_plugin.cpp(104,92): warning C4834: discarding return value of function with 'nodiscard' attribute [C:\temp\cnc-client\build\windows\plugins\flutter_nsd\flutter_nsd_plugin.vcxproj]
C:\temp\cnc-client\windows\flutter\ephemeral.plugin_symlinks\flutter_nsd\windows\flutter_nsd_plugin.cpp(104,120): warning C4834: discarding return value of function with 'nodiscard' attribute [C:\temp\cnc-client\build\windows\plugins\flutter_nsd\flutter_nsd_plugin.vcxproj]
C:\temp\cnc-client\windows\flutter\ephemeral.plugin_symlinks\flutter_nsd\windows\flutter_nsd_plugin.cpp(164,47): warning C4834: discarding return value of function with 'nodiscard' attribute [C:\temp\cnc-client\build\windows\plugins\flutter_nsd\flutter_nsd_plugin.vcxproj]
C:\temp\cnc-client\windows\flutter\ephemeral.plugin_symlinks\flutter_nsd\windows\flutter_nsd_plugin.cpp(164,66): warning C4834: discarding return value of function with 'nodiscard' attribute [C:\temp\cnc-client\build\windows\plugins\flutter_nsd\flutter_nsd_plugin.vcxproj]
Building Windows application... 67,5s
Build process failed.
Workaround:
Edit Windows/CMakelists.txt
Original:
target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
to replace with:
target_compile_options(${TARGET} PRIVATE /W4 /wd"4100")
I checked out the example project and changed the service name to '_http._tcp' which i am running locally.
The IOs detects it but not in Android.
I was thinking it would be good to migrate the plugin to the federated plugin structure to facilitate contribution. As I understand, this would enable developers to contribute platform implementations in their own repositories, without having to go through PRs. Also, it's how the packages maintained by the Flutter team (such as url_launcher and shared_preferences) are structured now.
The necessary steps are detailed here:
I think I'm done with step 1, you can preview it here. I'm not sure how to proceed though, since I can't publish under your name (of course). Let me know if you're interested in doing this. If you don't have the time / resources to do it, I understand, too!
Thanks for the library!
My tests so far indicate this is significantly better (faster!) than the multicast_dns
package.
Any plans to add support for Linux? Could we fallback to "multicast_dns" for Linux?
Discovery fails on some Android builds due to missing NEARBY_DEVICES permission in the manifest:
An easy workaround is to add this permission into the manifest of the app that uses the package
The plugin should have CI config in place via Github Actions.
In scope:
As discussed in #19, currently hostname
can be an IP address. It would be better to introduce new fields for storing ipv4 and ipv6. This affects all supported platforms (iOS, MacOS, Android and Windows).
I have set "Bonjour services" and "privacy - local network usage description" in info.plist according to the requirements of "note about IOS" in readme in “Flutter-nsd1.2.0", but I still can't obtain local network permissions,But android already does this,Is there anything else I haven't set up on ios?
Bonjour Services: "_connect1._tcp.”
The version number of my ios device is 14.7.1, and the model is iPhone6s Plus
NsdError (message: "stopDiscovery: MulticastLock under-locked nsdMulticastLock", cause: internalError)
NsdError (message: "stopDiscovery: MulticastLock under-locked nsdMulticastLock", cause: internalError)
I/flutter ( 2026): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 2026): │ #0 MethodChannelNsdPlatform.invoke. (package:nsd_platform_interface/src/method_channel_nsd_platform.dart:201:28)
I/flutter ( 2026): │ #1 _rootRunUnary (dart:async/zone.dart:1434:47)
I/flutter ( 2026): │ #2 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
I/flutter ( 2026): │ #3 _FutureListener.handleError (dart:async/future_impl.dart:177:22)
I/flutter ( 2026): │ #4 Future._propagateToListeners.handleError (dart:async/future_impl.dart:778:47)
I/flutter ( 2026): │ #5 Future._propagateToListeners (dart:async/future_impl.dart:799:13)
I/flutter ( 2026): │ #6 Future._completeError (dart:async/future_impl.dart:609:5)
I/flutter ( 2026): │ #7 _completeOnAsyncError (dart:async-patch/async_patch.dart:272:13)
I/flutter ( 2026): │ #8 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart)
I/flutter ( 2026): │ #9
I/flutter ( 2026): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 2026): │ 12:05:02.933 (+0:00:46.781794)
I/flutter ( 2026): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 2026): │ ⛔ ERROR OCCURS NsdError (message: "stopDiscovery: MulticastLock under-locked nsdMulticastLock", cause: internalError)
It looks like the example in the README.md getting started has been committed mid-changes:
It does not actually handle actual services (the onData
argument is unused), but uses onError
as if it was onData
.
I suppose it was supposed to use onError
like in the example
If I start the discovery and then stop it with stopDiscovery(), I receive a "NsdErrorCode.discoveryStopped" error in the stream listener. Is this by design or am I doing something wrong here?
Thanks!
This is my implementation:
flutterNsd.stream.listen((nsdServiceInfo) {
log('Discovered service name: ${nsdServiceInfo.name}');
log('Discovered service hostname/IP: ${nsdServiceInfo.hostname}');
log('Discovered service port: ${nsdServiceInfo.port}');
}, onError: (e) {
if (e is NsdError) {
log('NSD ERROR: ${e.errorCode}'); // Why does stopping NSD throws an error? Is this by design?
} else {
log('NSD ERROR: $e');
}
}, onDone: (){
log('NSD Done');
});
}
Hi!
I am playing with this as a replacement for flutter_mdns_plugin, followed docs and example, and I am getting an startDiscoveryFailed
nsd everytime. I am specifically looking for chromecast devices with:
await flutterNsd.discoverServices('_googlecast._tcp');
There is no other native log I can follow. This happens both on Android and iOS, both recent devices ...
Any idea?
E/AndroidRuntime( 553): FATAL EXCEPTION: NsdManager
E/AndroidRuntime( 553): Process: vip.mymei.remote, PID: 553
E/AndroidRuntime( 553): java.lang.IllegalArgumentException: listener not registered
E/AndroidRuntime( 553): at com.android.internal.util.Preconditions.checkArgument(Preconditions.java:59)
E/AndroidRuntime( 553): at android.net.nsd.NsdManager.getListenerKey(NsdManager.java:496)
E/AndroidRuntime( 553): at android.net.nsd.NsdManager.stopServiceDiscovery(NsdManager.java:636)
E/AndroidRuntime( 553): at com.nimroddayan.flutternsd.FlutterNsdPlugin$discoveryListener$1.onStartDiscoveryFailed(FlutterNsdPlugin.kt:195)
E/AndroidRuntime( 553): at android.net.nsd.NsdManager$ServiceHandler.handleMessage(NsdManager.java:412)
E/AndroidRuntime( 553): at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime( 553): at android.os.Looper.loopOnce(Looper.java:233)
E/AndroidRuntime( 553): at android.os.Looper.loop(Looper.java:334)
E/AndroidRuntime( 553): at android.os.HandlerThread.run(HandlerThread.java:67)
I/Process ( 553): Sending signal. PID: 553 SIG: 9
Hello
I wanted to try this plugin but I get the following error while compiling:
FAILURE: Build failed with an exception.
* What went wrong:
The Android Gradle plugin supports only Kotlin Gradle plugin version 1.5.20 and higher.
The following dependencies do not satisfy the required version:
project ':flutter_nsd' -> org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 858ms
Exception: Gradle task assembleDebug failed with exit code 1
I'm running the example app on windows and android
https://github.com/Nimrodda/flutter_nsd/tree/master/example
And I can see debug ouput, but nothing is ever posted to the listener
I can see this in my run output
192.168.101.100:5353 : answer osmc.local. A 192.168.101.100
[fe80::a72e:a506:d95d:fae7%65]:5353 : answer _device-info._tcp.local. PTR README._device-info._tcp.local. rclass 0x1 ttl 10 length 9
But flutterNsd.stream.listen never seems to be called
I've tried "_http._tcp." and "_device-info._tcp." which both return this server, but the services array and the UI are never updated to reflect that.
Any help would be appreciated
Contributions are welcome (#11 (comment))
When discovery gives multiple returned values immediately, the example code skips showing some of the values.
Is the following code in the example intended to work properly?
child: StreamBuilder(
stream: flutterNsd.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
services.add(snapshot.data as NsdServiceInfo);
Is the code guaranteed to add every found service to services
? In my environment it doesn't seem so. The following code shows more found services in console than what the UI does.
flutterNsd.stream.listen((value) {
print(value);
}
getting NsdErrorCode.startDiscoveryFailed when hot restart app
Windows build is failing. Not sure if it's only on Github Actions or in general. Haven't had the chance to try it, but just noticed it from @jnstahl 's PR.
This is very minor and doesn't concern me, but better to be valid than not.
I didn't make a pull request because probably you know better what you like to have.
Great, this is exactly what I was looking for 👍 The code seems short and succinct, so that's good. Do you have any plans to support deskop platforms?
I'm working with flutter_nsd example and an ESP8266. If I configure my ESP without service txt the example discovers him, but when I add a service txt the example couldn't discover him.
My router has service txt too and can't be discovered by the example.
I think is a Stream declaration problem
My ESP hostname is "lucho", here a print of the stream:
I added a service txt called "endpoint" "/stream"
Pay atention to line: 192.168.0.57:5353 : additional lucho._http._tcp.local. TXT endpoint = /stream
last record in this packet
I can see the broadcast but service not added
Thanks
the current Windows implementation returns hostnames, such as 'Android-5.local' when provided by the MDNS query results. However some windows hosts do not have the ability to resolve such a hostname and to establish a connection (apparently this ability relies on 3rd party packages such as Bonjour being installed).
Suggested fix:
unused variable causes static analysis errors and reduced pub points
I'm trying to use your library to discover devices on the network, but on iOS and MacOS it doesn't give back any hostAddresses
value.
I looked into the code and it doesn't do that at all.
Is that all we can get from those platforms? Or can you get it to work fully on those as well?
Have you thought about adding support for notifying about losing a service? I would think it's quite a relevant functionality to me.
I think the related APIs platform-wise are these:
Android: https://developer.android.com/reference/android/net/nsd/NsdManager.DiscoveryListener#onServiceLost(android.net.nsd.Nsd
ServiceInfo)
ios: https://developer.apple.com/documentation/foundation/netservicebrowserdelegate/1412917-netservicebrowser
NsdServiceInfo Class only shows: hostname, port, name and txt. Should have resolved IP
NetServiceBrowser is deprecated on iOS/MacOS. Need to investigate what should be used instead.
Using this in a flutter app for iOS and Android. While it works as expected on iOS, it does not discover the services on Android. This is on Android 14 (Samsung Galaxy A34 5G)
On Android, NsdServiceInfo.hostname returns the IP address instead of the hostname. On iOS it returns the hostname.
If an app using flutter_nsd is hot-restarted while discovery is active, calling startDiscovery() will fail.
In case timber logging is active it can be seen that a warning is printed, because NSD is already active, but no error is sent back to the app.
This is due to the exception handler in private fun startDiscovery(serviceType: String)
, which is doing nothing but printing the warning.
To get working discovery after a hot-restart, currently a cycle of discoverServices()
->stopDiscovery()
->startDiscovery()
is required. If the initial error would be notified back to the app it could detect that error condition and only then do an additional stop/start cycle.
Doing only stopDiscovery()
->startDiscovery()
after a restart is currently not working, because the onDiscoveryStopped
handler is called after startDiscovery()
only, as at the time of the initial stopDiscovery()
call, no method handler is set in the plugin's channel.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.