-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
on found doesnt find anything on Android (works fine on iOS) #128
Comments
Same issue for me as well, please help to resolve |
Same issue. Any solution? |
I have same issue. |
This npm package [1]: https://github.com/tableau/react-native-dns-lookup |
I got mine working, on Android it turns out battery optimizations were causing the resolve failures, I set com.android.server.NetworkPermissionConfig to 'don't optimise' in my android settings under: Apps & Notifications -> Advanced -> Special App Access -> Battery Optimization, now it works every time. |
Hello, has anyone found a solution to this problem? I am using react-native version 0.63.4 |
iOS "resolved" is working great. What's up with Android? Can't get it to go. |
This appears to be a duplicate of #85 And a related issue in a different repo: watson/bonjour#25 |
Using the Android debugger, I see this line being repeatedly invoked. I think this retry loop is intentional, but the NSD state never changes. |
I do not have any issue when there is only 1 device to resolve. Per this stack overflow question, it looks like there is a concurrency problem, so the issue can likely be fixed by resolving services one at a time. |
I've been struggling to get this package to work properly. Before anything here is my latest patch-package that aims to solve the issues. A detailed breakdown at the end. diff --git a/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroConfImplFactory.java b/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroConfImplFactory.java
index 3550238..27a4218 100644
--- a/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroConfImplFactory.java
+++ b/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroConfImplFactory.java
@@ -3,8 +3,6 @@ package com.balthazargronon.RCTZeroconf;
import com.balthazargronon.RCTZeroconf.nsd.NsdServiceImpl;
import com.balthazargronon.RCTZeroconf.rx2dnssd.DnssdImpl;
import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.bridge.ReactContext;
-
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
diff --git a/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/nsd/NsdServiceImpl.java b/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/nsd/NsdServiceImpl.java
index c59850d..6a90efd 100644
--- a/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/nsd/NsdServiceImpl.java
+++ b/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/nsd/NsdServiceImpl.java
@@ -1,6 +1,6 @@
package com.balthazargronon.RCTZeroconf.nsd;
-import android.annotation.SuppressLint;
+import java.lang.Thread;
import android.content.Context;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
@@ -17,12 +17,15 @@ import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.bridge.WritableNativeMap;
+import com.facebook.react.util.RNLog;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
public class NsdServiceImpl implements Zeroconf {
private NsdManager mNsdManager;
@@ -31,6 +34,7 @@ public class NsdServiceImpl implements Zeroconf {
private Map<String, NsdManager.RegistrationListener> mPublishedServices;
private ZeroconfModule zeroconfModule;
private ReactApplicationContext reactApplicationContext;
+ private final Semaphore semaphore = new Semaphore(1);
public NsdServiceImpl(ZeroconfModule zeroconfModule, ReactApplicationContext reactApplicationContext) {
this.zeroconfModule = zeroconfModule;
@@ -47,7 +51,7 @@ public class NsdServiceImpl implements Zeroconf {
this.stop();
if (multicastLock == null) {
- @SuppressLint("WifiManagerLeak") WifiManager wifi = (WifiManager) getReactApplicationContext().getSystemService(Context.WIFI_SERVICE);
+ WifiManager wifi = (WifiManager) getReactApplicationContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
multicastLock = wifi.createMulticastLock("multicastLock");
multicastLock.setReferenceCounted(true);
multicastLock.acquire();
@@ -57,35 +61,42 @@ public class NsdServiceImpl implements Zeroconf {
@Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
String error = "Starting service discovery failed with code: " + errorCode;
- zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_ERROR, error);
+ // zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_ERROR, error);
}
@Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
String error = "Stopping service discovery failed with code: " + errorCode;
- zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_ERROR, error);
+ // zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_ERROR, error);
}
@Override
public void onDiscoveryStarted(String serviceType) {
System.out.println("On Discovery Started");
- zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_START, null);
+ // zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_START, null);
}
@Override
public void onDiscoveryStopped(String serviceType) {
System.out.println("On Discovery Stopped");
- zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_STOP, null);
+ // zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_STOP, null);
}
@Override
public void onServiceFound(NsdServiceInfo serviceInfo) {
- System.out.println("On Service Found");
WritableMap service = new WritableNativeMap();
service.putString(ZeroconfModule.KEY_SERVICE_NAME, serviceInfo.getServiceName());
- zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_FOUND, service);
- mNsdManager.resolveService(serviceInfo, new NsdServiceImpl.ZeroResolveListener());
+ // put it into a "thread" so the semaphore doesn't block everything
+ Executors.newSingleThreadExecutor().submit(() -> {
+ try {
+ semaphore.acquire();
+ mNsdManager.resolveService(serviceInfo, new NsdServiceImpl.ZeroResolveListener());
+ } catch (InterruptedException e) {
+ RNLog.e("Zeroconf: Could not aquire semaphore");
+ }
+ });
+
}
@Override
@@ -162,18 +173,22 @@ public class NsdServiceImpl implements Zeroconf {
private class ZeroResolveListener implements NsdManager.ResolveListener {
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
- if (errorCode == NsdManager.FAILURE_ALREADY_ACTIVE) {
- mNsdManager.resolveService(serviceInfo, this);
- } else {
- String error = "Resolving service failed with code: " + errorCode;
- zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_ERROR, error);
- }
+ String error = "Resolving service failed with code: " + errorCode;
+ zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_ERROR, error);
+ semaphore.release();
+// if (errorCode == NsdManager.FAILURE_ALREADY_ACTIVE) {
+// mNsdManager.resolveService(serviceInfo, this);
+// } else {
+// String error = "Resolving service failed with code: " + errorCode;
+// zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_ERROR, error);
+// }
}
@Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
WritableMap service = serviceInfoToMap(serviceInfo);
zeroconfModule.sendEvent(getReactApplicationContext(), ZeroconfModule.EVENT_RESOLVE, service);
+ semaphore.release();
}
}
diff --git a/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/rx2dnssd/DnssdImpl.java b/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/rx2dnssd/DnssdImpl.java
index fda45d6..1cf6027 100644
--- a/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/rx2dnssd/DnssdImpl.java
+++ b/node_modules/react-native-zeroconf/android/src/main/java/com/balthazargronon/RCTZeroconf/rx2dnssd/DnssdImpl.java
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.util.Log;
+import android.os.Build;
import com.balthazargronon.RCTZeroconf.Zeroconf;
import com.balthazargronon.RCTZeroconf.ZeroconfModule;
@@ -17,6 +18,7 @@ import com.facebook.react.bridge.WritableNativeMap;
import com.github.druk.rx2dnssd.BonjourService;
import com.github.druk.rx2dnssd.Rx2Dnssd;
import com.github.druk.rx2dnssd.Rx2DnssdBindable;
+import com.github.druk.rx2dnssd.Rx2DnssdEmbedded;
import java.net.InetAddress;
import java.util.HashMap;
@@ -49,7 +51,11 @@ public class DnssdImpl implements Zeroconf {
this.reactApplicationContext = reactApplicationContext;
mPublishedServices = new HashMap<String, BonjourService>();
mRegisteredDisposables = new HashMap<String, Disposable>();
- rxDnssd = new Rx2DnssdBindable(reactApplicationContext);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ rxDnssd = new Rx2DnssdEmbedded(reactApplicationContext);
+ } else {
+ rxDnssd = new Rx2DnssdBindable(reactApplicationContext);
+ }
}
@Override
@@ -57,7 +63,7 @@ public class DnssdImpl implements Zeroconf {
this.stop();
if (multicastLock == null) {
- @SuppressLint("WifiManagerLeak") WifiManager wifi = (WifiManager) reactApplicationContext.getSystemService(Context.WIFI_SERVICE);
+ WifiManager wifi = (WifiManager) reactApplicationContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
multicastLock = wifi.createMulticastLock("multicastLock");
multicastLock.setReferenceCounted(true);
multicastLock.acquire();
diff --git a/node_modules/react-native-zeroconf/ios/RNZeroconf/RNZeroconf.m b/node_modules/react-native-zeroconf/ios/RNZeroconf/RNZeroconf.m
index 1ff5371..e0fe5ef 100644
--- a/node_modules/react-native-zeroconf/ios/RNZeroconf/RNZeroconf.m
+++ b/node_modules/react-native-zeroconf/ios/RNZeroconf/RNZeroconf.m
@@ -85,8 +85,8 @@ RCT_EXPORT_METHOD(unregisterService:(NSString *) serviceName)
return;
}
- NSDictionary *serviceInfo = [RNNetServiceSerializer serializeServiceToDictionary:service resolved:NO];
- [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNZeroconfFound" body:serviceInfo];
+ // NSDictionary *serviceInfo = [RNNetServiceSerializer serializeServiceToDictionary:service resolved:NO];
+ // [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNZeroconfFound" body:serviceInfo];
// resolving services must be strongly referenced or they will be garbage collected
// and will never resolve or timeout. Here is a detailed rundown of my findings and workarounds:
I also started with a new JSI C++ implementation but emitting events from Java->C++->Java->C++ is too complex and I also have to deal with memory sharing and the awfulness that is the JNI interface. I haven't given up, but the resulting code is a lot harder to understand that the current implementation and might still not work. I still need to test this latest package thoroughly but I've tried a lot of things and thought it might be useful if somebody has already worked around this issue |
It seems that Android cached previously founded devices and send this in the question request. But the problem is that the app already know them but don't has IP Adresses on Android. It's possible to check that with Wireshark and filter by IP Adresses of mobile and wanted devices |
I don't really know why, but adding DNSSD like this |
on.start runs per the console.log callback, but on.scan never triggers the callback (as if not finding anything). The exact same code works fine in iOS, and I have added the user-permissions mentioned:
The text was updated successfully, but these errors were encountered: