diff --git a/android/src/main/java/com/tradle/react/UdpSocketClient.java b/android/src/main/java/com/tradle/react/UdpSocketClient.java index 63e2479..15d6526 100644 --- a/android/src/main/java/com/tradle/react/UdpSocketClient.java +++ b/android/src/main/java/com/tradle/react/UdpSocketClient.java @@ -39,6 +39,7 @@ public final class UdpSocketClient implements UdpReceiverTask.OnDataReceivedList private final Map mPendingSends; private DatagramSocket mSocket; + private boolean mIsMulticastSocket = false; private UdpSocketClient(Builder builder) { this.mReceiverListener = builder.receiverListener; @@ -52,7 +53,7 @@ public final class UdpSocketClient implements UdpReceiverTask.OnDataReceivedList * @return boolean true IF the socket is part of a multi-cast group. */ public boolean isMulticast() { - return (mSocket != null && mSocket instanceof MulticastSocket); + return mIsMulticastSocket; } /** @@ -68,7 +69,7 @@ public final class UdpSocketClient implements UdpReceiverTask.OnDataReceivedList * binding. */ public void bind(Integer port, @Nullable String address) throws IOException { - mSocket = new DatagramSocket(null); + mSocket = new MulticastSocket(null); mReceiverTask = new UdpReceiverTask(); @@ -101,25 +102,8 @@ public final class UdpSocketClient implements UdpReceiverTask.OnDataReceivedList throw new IllegalStateException("Socket is not bound."); } - if (!(mSocket instanceof MulticastSocket)) { - // cancel the current receiver task - if (mReceiverTask != null) { - mReceiverTask.cancel(true); - } - - mReceiverTask = new UdpReceiverTask(); - - // tear down the DatagramSocket, and rebuild as a MulticastSocket - final int port = mSocket.getLocalPort(); - mSocket.close(); - mSocket = new MulticastSocket(port); - - // begin listening for data in the background - mReceiverTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, - new Pair(mSocket, this)); - } - ((MulticastSocket) mSocket).joinGroup(InetAddress.getByName(address)); + mIsMulticastSocket = true; } /** @@ -130,9 +114,8 @@ public final class UdpSocketClient implements UdpReceiverTask.OnDataReceivedList * @throws IOException */ public void dropMembership(String address) throws UnknownHostException, IOException { - if (mSocket instanceof MulticastSocket) { - ((MulticastSocket) mSocket).leaveGroup(InetAddress.getByName(address)); - } + ((MulticastSocket) mSocket).leaveGroup(InetAddress.getByName(address)); + mIsMulticastSocket = false; } /** diff --git a/android/src/main/java/com/tradle/react/UdpSockets.java b/android/src/main/java/com/tradle/react/UdpSockets.java index 15af71d..3b8f5d4 100644 --- a/android/src/main/java/com/tradle/react/UdpSockets.java +++ b/android/src/main/java/com/tradle/react/UdpSockets.java @@ -177,22 +177,26 @@ public final class UdpSockets extends ReactContextBaseJavaModule mMulticastLock.setReferenceCounted(true); } - if (!client.isMulticast()) { - // acquire the multi-cast lock, IF this is the - // first addMembership call for this client. + try { mMulticastLock.acquire(); - } - - try { client.addMembership(multicastAddress); } catch (IllegalStateException ise) { // an exception occurred + if (mMulticastLock != null && mMulticastLock.isHeld()) { + mMulticastLock.release(); + } FLog.e(TAG, "addMembership", ise); } catch (UnknownHostException uhe) { // an exception occurred + if (mMulticastLock != null && mMulticastLock.isHeld()) { + mMulticastLock.release(); + } FLog.e(TAG, "addMembership", uhe); } catch (IOException ioe) { // an exception occurred + if (mMulticastLock != null && mMulticastLock.isHeld()) { + mMulticastLock.release(); + } FLog.e(TAG, "addMembership", ioe); } } @@ -217,6 +221,10 @@ public final class UdpSockets extends ReactContextBaseJavaModule } catch (IOException ioe) { // an exception occurred FLog.e(TAG, "dropMembership", ioe); + } finally { + if (mMulticastLock != null && mMulticastLock.isHeld()) { + mMulticastLock.release(); + } } } }.execute(); @@ -263,7 +271,7 @@ public final class UdpSockets extends ReactContextBaseJavaModule return; } - if (client.isMulticast() && mMulticastLock.isHeld()) { + if (mMulticastLock != null && mMulticastLock.isHeld() && client.isMulticast()) { // drop the multi-cast lock if this is a multi-cast client mMulticastLock.release(); }