From e8f2f76f8f636629a6af30f8f69a7de12e98fe8d Mon Sep 17 00:00:00 2001 From: Andoni Vianez Ulloa Date: Tue, 11 Sep 2018 16:12:25 +0200 Subject: [PATCH 1/7] Fixed uncaught error throwing sometimes when zeroConf module was already initialized Fixed bug in zeroConf scan method; as say in docs, it was emitting update method instead start(). Added second verification in Java onServiceResolved method, to ensure that hostAddress has been provided in the object Now, in every "update" emit, updated service name is provided. New method getResolvedServices added, to get only fully resolved services. Stop method converted to async method; now waits until process finishes. Docs fixed and updated. --- README.md | 12 ++++++-- .../RCTZeroconf/ZeroconfModule.java | 6 ++++ package.json | 2 +- src/index.js | 30 ++++++++++++------- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 4249f74..d7c01c0 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,15 @@ This will initialize the scan from the `Zeroconf` instance. Will stop another sc ###### `stop()` Stop the scan -If any scan is running, stop it. Otherwise do nothing. +If any scan is running, stop it. Otherwise do nothing. Be sure to do this when the apps go to background, avoids potential memory leaks. ###### `getServices()` Returns resolved services -Will return all names of services that have been resolved. +Will return all names of services that have been found or resolved. + +###### `getResolvedServices()` Returns resolved services + +Will return all names of services that have been fully resolved. ###### `removeDeviceListeners()` Remove listeners @@ -76,5 +80,7 @@ Broadcast a service object once it is fully resolved Broadcast a service name removed from the network. -###### `update` Triggered either when a service is found or removed +###### `update` +Triggered either when a service is found, resolved or removed. It returns the service that has been updated. + ###### `error` Triggered when an error occurs diff --git a/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java b/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java index 2c470ab..e34bc5f 100644 --- a/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java +++ b/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java @@ -156,6 +156,12 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) { WritableArray addresses = new WritableNativeArray(); addresses.pushString(serviceInfo.getHost().getHostAddress()); + + if (serviceInfo.getHost().getHostAddress().equals("")) { + sendEvent(getReactApplicationContext(), EVENT_ERROR, "Empty serviceName"); + mNsdManager.resolveService(serviceInfo, this); + return; + } service.putArray(KEY_SERVICE_ADDRESSES, addresses); diff --git a/package.json b/package.json index 0e489bf..512c672 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "react-native-zeroconf", "version": "0.9.0", "description": "A Zeroconf discovery utility for react-native", - "main": "dist", + "main": "src", "scripts": { "lint": "eslint src/*.js", "build": "rm -rf dist && mkdir dist && babel src -o dist/index.js" diff --git a/src/index.js b/src/index.js index 00963bb..4d7e5f0 100644 --- a/src/index.js +++ b/src/index.js @@ -9,6 +9,7 @@ export default class Zeroconf extends EventEmitter { super(props) this._services = {} + this._resolvedServices = {} this._dListeners = {} this.addDeviceListeners() @@ -20,7 +21,7 @@ export default class Zeroconf extends EventEmitter { addDeviceListeners () { if (Object.keys(this._dListeners).length) { - return this.emit('error', new Error('RNZeroconf listeners already in place.')) + return this.emit('error', 'RNZeroconf listeners already in place.') } this._dListeners.start = DeviceEventEmitter.addListener('RNZeroconfStart', () => this.emit('start')) @@ -32,8 +33,8 @@ export default class Zeroconf extends EventEmitter { const { name } = service this._services[name] = service - this.emit('found', name) - this.emit('update') + this.emit('found', service) + this.emit('update', service) }) this._dListeners.remove = DeviceEventEmitter.addListener('RNZeroconfRemove', service => { @@ -42,16 +43,17 @@ export default class Zeroconf extends EventEmitter { delete this._services[name] - this.emit('remove', name) - this.emit('update') + this.emit('remove', service) + this.emit('update', service) }) this._dListeners.resolved = DeviceEventEmitter.addListener('RNZeroconfResolved', service => { if (!service || !service.name) { return } + this._resolvedServices[service.name] = service this._services[service.name] = service this.emit('resolved', service) - this.emit('update') + this.emit('update', service) }) } @@ -65,27 +67,35 @@ export default class Zeroconf extends EventEmitter { } /** - * Get all the services already resolved + * Get all the services fully resolved or not */ getServices () { return this._services } + /** + * Get all the services fully resolved + */ + getResolvedServices () { + return this._resolvedServices + } + /** * Scan for Zeroconf services, * Defaults to _http._tcp. on local domain */ scan (type = 'http', protocol = 'tcp', domain = 'local.') { this._services = {} - this.emit('update') + this._resolvedServices = {} + this.emit('start') RNZeroconf.scan(type, protocol, domain) } /** * Stop current scan if any */ - stop () { - RNZeroconf.stop() + async stop () { + await RNZeroconf.stop() } } From 9159a0082838d4504ef29771623b1589ef4384a2 Mon Sep 17 00:00:00 2001 From: Andoni Vianez Ulloa Date: Tue, 11 Sep 2018 17:15:48 +0200 Subject: [PATCH 2/7] Fixed app crash when error events comes; an String was passing to a function that was only accepting Objects. Added support in the same method for both types. --- .../RCTZeroconf/ZeroconfModule.java | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java b/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java index e34bc5f..48e83e8 100644 --- a/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java +++ b/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java @@ -64,23 +64,23 @@ public void scan(String type, String protocol, String domain) { @Override public void onStartDiscoveryFailed(String serviceType, int errorCode) { String error = "Starting service discovery failed with code: " + errorCode; - sendEvent(getReactApplicationContext(), EVENT_ERROR, error); + sendEvent(getReactApplicationContext(), EVENT_ERROR, null, error); } @Override public void onStopDiscoveryFailed(String serviceType, int errorCode) { String error = "Stopping service discovery failed with code: " + errorCode; - sendEvent(getReactApplicationContext(), EVENT_ERROR, error); + sendEvent(getReactApplicationContext(), EVENT_ERROR, null, error); } @Override public void onDiscoveryStarted(String serviceType) { - sendEvent(getReactApplicationContext(), EVENT_START, null); + sendEvent(getReactApplicationContext(), EVENT_START, null, null); } @Override public void onDiscoveryStopped(String serviceType) { - sendEvent(getReactApplicationContext(), EVENT_STOP, null); + sendEvent(getReactApplicationContext(), EVENT_STOP, null, null); } @Override @@ -88,7 +88,7 @@ public void onServiceFound(NsdServiceInfo serviceInfo) { WritableMap service = new WritableNativeMap(); service.putString(KEY_SERVICE_NAME, serviceInfo.getServiceName()); - sendEvent(getReactApplicationContext(), EVENT_FOUND, service); + sendEvent(getReactApplicationContext(), EVENT_FOUND, service, null); mNsdManager.resolveService(serviceInfo, new ZeroResolveListener()); } @@ -96,7 +96,7 @@ public void onServiceFound(NsdServiceInfo serviceInfo) { public void onServiceLost(NsdServiceInfo serviceInfo) { WritableMap service = new WritableNativeMap(); service.putString(KEY_SERVICE_NAME, serviceInfo.getServiceName()); - sendEvent(getReactApplicationContext(), EVENT_REMOVE, service); + sendEvent(getReactApplicationContext(), EVENT_REMOVE, service, null); } }; @@ -114,10 +114,19 @@ public void stop() { protected void sendEvent(ReactContext reactContext, String eventName, - @Nullable Object params) { - reactContext + @Nullable Object params, + @Nullable String errorString + ) { + if (errorString == null){ + reactContext .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit(eventName, params); + }else{ + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(eventName, errorString); + } + } private class ZeroResolveListener implements NsdManager.ResolveListener { @@ -127,7 +136,7 @@ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { mNsdManager.resolveService(serviceInfo, this); } else { String error = "Resolving service failed with code: " + errorCode; - sendEvent(getReactApplicationContext(), EVENT_ERROR, error); + sendEvent(getReactApplicationContext(), EVENT_ERROR, null, error); } } @@ -148,7 +157,7 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) { txtRecords.putString(String.format(Locale.getDefault(), "%s", key), String.format(Locale.getDefault(), "%s", recordValue != null ? new String(recordValue, "UTF_8") : "")); } catch (UnsupportedEncodingException e) { String error = "Failed to encode txtRecord: " + e; - sendEvent(getReactApplicationContext(), EVENT_ERROR, error); + sendEvent(getReactApplicationContext(), EVENT_ERROR, null, error); } } @@ -158,14 +167,15 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) { addresses.pushString(serviceInfo.getHost().getHostAddress()); if (serviceInfo.getHost().getHostAddress().equals("")) { - sendEvent(getReactApplicationContext(), EVENT_ERROR, "Empty serviceName"); + String notIpErrorString = "Ip not resolved"; + sendEvent(getReactApplicationContext(), EVENT_ERROR, null, notIpErrorString); mNsdManager.resolveService(serviceInfo, this); return; } service.putArray(KEY_SERVICE_ADDRESSES, addresses); - sendEvent(getReactApplicationContext(), EVENT_RESOLVE, service); + sendEvent(getReactApplicationContext(), EVENT_RESOLVE, service, null); } } From 7db837b823fbd3af199a7a0e13c15c81e109f1b0 Mon Sep 17 00:00:00 2001 From: Andoni Vianez Ulloa Date: Wed, 12 Sep 2018 09:26:45 +0200 Subject: [PATCH 3/7] Fixed emit on latest change, as I was passing an string to the emit and this is not possible. --- .../java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java b/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java index 48e83e8..4e2f13c 100644 --- a/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java +++ b/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java @@ -122,9 +122,12 @@ protected void sendEvent(ReactContext reactContext, .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit(eventName, params); }else{ + WritableMap payload = new WritableNativeMap(); + // Put data to map + payload.putString("error", errorString); reactContext .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) - .emit(eventName, errorString); + .emit(eventName, payload); } } From 2e3c9eecf6784fde7cce9588b6c14a6801e7c0fb Mon Sep 17 00:00:00 2001 From: Andoni Vianez Ulloa Date: Mon, 17 Sep 2018 12:53:07 +0200 Subject: [PATCH 4/7] =?UTF-8?q?Fix;=20when=20a=20service=20emited=20BYE=20?= =?UTF-8?q?message,=20it=20wasn=C2=B4t=20being=20removed=20from=20resolved?= =?UTF-8?q?Services.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.js b/src/index.js index 4d7e5f0..74fc308 100644 --- a/src/index.js +++ b/src/index.js @@ -42,6 +42,7 @@ export default class Zeroconf extends EventEmitter { const { name } = service delete this._services[name] + delete this._resolvedServices[name] this.emit('remove', service) this.emit('update', service) From 649e14053f39b6b0cd287e4a943bc59ce194fe68 Mon Sep 17 00:00:00 2001 From: Andoni Vianez Ulloa Date: Tue, 18 Sep 2018 18:01:09 +0200 Subject: [PATCH 5/7] Changed "error" event key, as it throws a JS Error Exception and produces an app crash in release (bundled) mode. Now, the error event has a different key that can be correctly handled with a listener. It fixes "Uncaught, unhandled 'error' event (-72000)" issue. --- src/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 74fc308..567d57f 100644 --- a/src/index.js +++ b/src/index.js @@ -26,7 +26,8 @@ export default class Zeroconf extends EventEmitter { this._dListeners.start = DeviceEventEmitter.addListener('RNZeroconfStart', () => this.emit('start')) this._dListeners.stop = DeviceEventEmitter.addListener('RNZeroconfStop', () => this.emit('stop')) - this._dListeners.error = DeviceEventEmitter.addListener('RNZeroconfError', err => this.emit('error', err)) + this._dListeners.error = DeviceEventEmitter.addListener('RNZeroconfError', (err) => this.emit('errorEvent', err) + ) this._dListeners.found = DeviceEventEmitter.addListener('RNZeroconfFound', service => { if (!service || !service.name) { return } From 71a28dbfb278140a588bbb3b2a86c1c94107eef3 Mon Sep 17 00:00:00 2001 From: Andoni Vianez Ulloa Date: Tue, 18 Sep 2018 18:07:27 +0200 Subject: [PATCH 6/7] Docs updated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d7c01c0..d380b92 100644 --- a/README.md +++ b/README.md @@ -83,4 +83,4 @@ Broadcast a service name removed from the network. ###### `update` Triggered either when a service is found, resolved or removed. It returns the service that has been updated. -###### `error` Triggered when an error occurs +###### `errorEvent` Triggered when an error occurs. It returns the error code as object (Android) or int(iOS) From ea65a184a8032a5e748f7069addb669c45697e6c Mon Sep 17 00:00:00 2001 From: Andoni Vianez Ulloa Date: Wed, 19 Sep 2018 15:53:21 +0200 Subject: [PATCH 7/7] =?UTF-8?q?Updated=20package.json=C2=B4s=20version=20t?= =?UTF-8?q?o=201.0.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 512c672..7df39b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-zeroconf", - "version": "0.9.0", + "version": "1.0.0", "description": "A Zeroconf discovery utility for react-native", "main": "src", "scripts": {