react-native-udp icon indicating copy to clipboard operation
react-native-udp copied to clipboard

setBroadcast(true) hangs on Android

Open shynst opened this issue 5 years ago • 7 comments

In order to send broadcast messages we need to call setBroadcast() first. However this method hangs and never returns!

protected void doInBackgroundGuarded(Void... params) {
	UdpSocketClient client = findClient(cId, callback);
	if (client == null) {
		return;
	}

	try {
		client.setBroadcast(flag);
		// **** we never get there!

		callback.invoke();
	} catch (SocketException e) {
		callback.invoke(UdpErrorUtil.getError(null, e.getMessage()));
	}
}

I tested in Android emulator and with a Samsung Galaxy S8. Both running on Android API 28. Any ideas what is going on here?

shynst avatar Mar 10 '19 13:03 shynst

Hi, I got the same issue but in a different way. I just changed setBroadcast to work with iOS but still Android hangs after a while. I found that with android sending to broadcast IP is enough we don't have call setBroadcast(true) but it still hangs at the send function. Here is part of my code and my log. Please look at the last line and you can see see that it logs binded but not sent

      logInfo(`Sending ${msg.messageType} to Broadcast  ID: ${msg.id}`);
      var socket = dgram.createSocket("udp4");
      logInfo(`Created ${msg.messageType} to Broadcast  ID: ${msg.id}`);
      const data = toByteArray(JSON.stringify(msg, replacer));
      socket.bind(randomPort(), undefined, (err) => {
        logInfo(`Binded ${msg.messageType} to Broadcast  ID: ${msg.id}`);
        if (err) {
          logWarning(err);
          reject(err);
          return;
        }
        if (Platform.OS === "ios")
          socket.setBroadcast(true);
        getNetworkInfo().then(ni => {
          const br = getBroadcastAddress(ni!.details.ipAddress!, ni!.details.subnet!);
          try {
            setTimeout(() => {
              socket.close(() => {
                logInfo("Closing with Timeout " + msg.messageType + " from broadcast ID: " + msg.id);
                reject(err);
              });
            }, 3000);
            socket.send(data, 0, data.length, GUZZLO_PORT, br, err => {
              // Android freezes here
              logInfo(`Sent ${msg.messageType} to Broadcast  ID: ${msg.id}`);
[Wed May 20 2020 20:20:33.629]  INFO      Lenovo T : Sending HANDSHAKE to Broadcast  ID: 1589995234191
[Wed May 20 2020 20:20:33.639]  INFO      Lenovo T : Created HANDSHAKE to Broadcast  ID: 1589995234191
[Wed May 20 2020 20:20:33.644]  INFO      Lenovo T : Binded HANDSHAKE to Broadcast  ID: 1589995234191
[Wed May 20 2020 20:20:33.655]  INFO      Lenovo T : Sent HANDSHAKE to Broadcast  ID: 1589995234191
[Wed May 20 2020 20:20:33.665]  INFO      Lenovo T : Closing HANDSHAKE from broadcast ID: 1589995234191
[Wed May 20 2020 20:20:33.672]  INFO      Lenovo T : Scan complete 1 node found
[Wed May 20 2020 20:20:33.747]  INFO      iPad Air : Received HANDSHAKE from 192.168.1.41:29663 ID: 1589995234191
[Wed May 20 2020 20:20:33.756]  INFO      iPad Air : Sending  HANDSHAKEBACK to 192.168.1.41:12001  ID: 1589995233755
[Wed May 20 2020 20:20:33.775]  INFO      Lenovo T : Received HANDSHAKEBACK from 192.168.1.43:55821 ID: 1589995233755
[Wed May 20 2020 20:20:36.673]  INFO      Lenovo T : Closing with Timeout HANDSHAKE from broadcast ID: 1589995234191
[Wed May 20 2020 20:20:45.190]  INFO      iPad Air : Sending HANDSHAKE to Broadcast  ID: 1589995245018
[Wed May 20 2020 20:20:45.200]  INFO      iPad Air : Created HANDSHAKE to Broadcast  ID: 1589995245018
[Wed May 20 2020 20:20:45.200]  INFO      iPad Air : Binded HANDSHAKE to Broadcast  ID: 1589995245018
[Wed May 20 2020 20:20:45.210]  INFO      iPad Air : Sent HANDSHAKE to Broadcast  ID: 1589995245018
[Wed May 20 2020 20:20:45.230]  INFO      iPad Air : Closing HANDSHAKE from broadcast ID: 1589995245018
[Wed May 20 2020 20:20:45.230]  INFO      iPad Air : Scan complete 1 node found
[Wed May 20 2020 20:20:45.141]  INFO      Lenovo T : Received HANDSHAKE from 192.168.1.43:56298 ID: 1589995245018
[Wed May 20 2020 20:20:45.433]  INFO      Lenovo T : Sending  HANDSHAKEBACK to 192.168.1.43:12001  ID: 1589995246008
[Wed May 20 2020 20:20:45.450]  INFO      iPad Air : Received HANDSHAKEBACK from 192.168.1.41:58361 ID: 1589995246008
[Wed May 20 2020 20:20:48.200]  INFO      iPad Air : Closing with Timeout HANDSHAKE from broadcast ID: 1589995245018
[Wed May 20 2020 20:20:53.651]  INFO      Lenovo T : Sending HANDSHAKE to Broadcast  ID: 1589995254197
[Wed May 20 2020 20:20:53.654]  INFO      Lenovo T : Created HANDSHAKE to Broadcast  ID: 1589995254197
[Wed May 20 2020 20:20:53.667]  INFO      Lenovo T : Binded HANDSHAKE to Broadcast  ID: 1589995254197

serayuzgur avatar May 20 '20 17:05 serayuzgur

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community attention? This issue may be closed if no further activity occurs.

github-actions[bot] avatar Jun 22 '20 00:06 github-actions[bot]

Hi, I got the same issue but in a different way. I just changed setBroadcast to work with iOS but still Android hangs after a while. I found that with android sending to broadcast IP is enough we don't have call setBroadcast(true) but it still hangs at the send function. Here is part of my code and my log. Please look at the last line and you can see see that it logs binded but not sent

      logInfo(`Sending ${msg.messageType} to Broadcast  ID: ${msg.id}`);
      var socket = dgram.createSocket("udp4");
      logInfo(`Created ${msg.messageType} to Broadcast  ID: ${msg.id}`);
      const data = toByteArray(JSON.stringify(msg, replacer));
      socket.bind(randomPort(), undefined, (err) => {
        logInfo(`Binded ${msg.messageType} to Broadcast  ID: ${msg.id}`);
        if (err) {
          logWarning(err);
          reject(err);
          return;
        }
        if (Platform.OS === "ios")
          socket.setBroadcast(true);
        getNetworkInfo().then(ni => {
          const br = getBroadcastAddress(ni!.details.ipAddress!, ni!.details.subnet!);
          try {
            setTimeout(() => {
              socket.close(() => {
                logInfo("Closing with Timeout " + msg.messageType + " from broadcast ID: " + msg.id);
                reject(err);
              });
            }, 3000);
            socket.send(data, 0, data.length, GUZZLO_PORT, br, err => {
              // Android freezes here
              logInfo(`Sent ${msg.messageType} to Broadcast  ID: ${msg.id}`);
[Wed May 20 2020 20:20:33.629]  INFO      Lenovo T : Sending HANDSHAKE to Broadcast  ID: 1589995234191
[Wed May 20 2020 20:20:33.639]  INFO      Lenovo T : Created HANDSHAKE to Broadcast  ID: 1589995234191
[Wed May 20 2020 20:20:33.644]  INFO      Lenovo T : Binded HANDSHAKE to Broadcast  ID: 1589995234191
[Wed May 20 2020 20:20:33.655]  INFO      Lenovo T : Sent HANDSHAKE to Broadcast  ID: 1589995234191
[Wed May 20 2020 20:20:33.665]  INFO      Lenovo T : Closing HANDSHAKE from broadcast ID: 1589995234191
[Wed May 20 2020 20:20:33.672]  INFO      Lenovo T : Scan complete 1 node found
[Wed May 20 2020 20:20:33.747]  INFO      iPad Air : Received HANDSHAKE from 192.168.1.41:29663 ID: 1589995234191
[Wed May 20 2020 20:20:33.756]  INFO      iPad Air : Sending  HANDSHAKEBACK to 192.168.1.41:12001  ID: 1589995233755
[Wed May 20 2020 20:20:33.775]  INFO      Lenovo T : Received HANDSHAKEBACK from 192.168.1.43:55821 ID: 1589995233755
[Wed May 20 2020 20:20:36.673]  INFO      Lenovo T : Closing with Timeout HANDSHAKE from broadcast ID: 1589995234191
[Wed May 20 2020 20:20:45.190]  INFO      iPad Air : Sending HANDSHAKE to Broadcast  ID: 1589995245018
[Wed May 20 2020 20:20:45.200]  INFO      iPad Air : Created HANDSHAKE to Broadcast  ID: 1589995245018
[Wed May 20 2020 20:20:45.200]  INFO      iPad Air : Binded HANDSHAKE to Broadcast  ID: 1589995245018
[Wed May 20 2020 20:20:45.210]  INFO      iPad Air : Sent HANDSHAKE to Broadcast  ID: 1589995245018
[Wed May 20 2020 20:20:45.230]  INFO      iPad Air : Closing HANDSHAKE from broadcast ID: 1589995245018
[Wed May 20 2020 20:20:45.230]  INFO      iPad Air : Scan complete 1 node found
[Wed May 20 2020 20:20:45.141]  INFO      Lenovo T : Received HANDSHAKE from 192.168.1.43:56298 ID: 1589995245018
[Wed May 20 2020 20:20:45.433]  INFO      Lenovo T : Sending  HANDSHAKEBACK to 192.168.1.43:12001  ID: 1589995246008
[Wed May 20 2020 20:20:45.450]  INFO      iPad Air : Received HANDSHAKEBACK from 192.168.1.41:58361 ID: 1589995246008
[Wed May 20 2020 20:20:48.200]  INFO      iPad Air : Closing with Timeout HANDSHAKE from broadcast ID: 1589995245018
[Wed May 20 2020 20:20:53.651]  INFO      Lenovo T : Sending HANDSHAKE to Broadcast  ID: 1589995254197
[Wed May 20 2020 20:20:53.654]  INFO      Lenovo T : Created HANDSHAKE to Broadcast  ID: 1589995254197
[Wed May 20 2020 20:20:53.667]  INFO      Lenovo T : Binded HANDSHAKE to Broadcast  ID: 1589995254197

Hi @serayuzgur Did you find any solution?

baharb avatar Jul 12 '20 10:07 baharb

Hi @shynst @serayuzgur - did you find a solution?

nishmeht7 avatar Jun 18 '21 18:06 nishmeht7

@nishmeht7: I did fix it 2 years ago (works very well in production code):

It seems we must not call setBroadcast() after the receiving thread was started, since this will result in a deadlock. Therefore I removed automatic start of receive on bind and introduced a new method startReveiving().

See details in my commit above.

shynst avatar Jun 18 '21 20:06 shynst

@shynst Thank you so much, you're a life saver!

nishmeht7 avatar Jun 23 '21 04:06 nishmeht7

Hi shynst, When you mean production mode, is it Release mode? My udp works in Debug Mode but not on Release Mode in Android and iOS.

npx react-native run-android --mode release --deviceId R9TWA08193A This will result to UDP not sending any. Nothing at all. My UDP servers do not receive anything.

npx react-native run-android --deviceId R9TWA08193A This Debug mode works great! The UDP servers will respond and the App receives the data.

I am really stumped because on Release mode you don't see any logs on what is happening.

gibo77 avatar Nov 12 '23 02:11 gibo77