Merge pull request #27 from aprock/master

android switch to MulticastSocket for sockets
This commit is contained in:
Andy Prock 2016-09-30 09:45:10 -07:00 committed by GitHub
commit 2f43357118
2 changed files with 21 additions and 30 deletions

View File

@ -39,6 +39,7 @@ public final class UdpSocketClient implements UdpReceiverTask.OnDataReceivedList
private final Map<UdpSenderTask, Callback> mPendingSends; private final Map<UdpSenderTask, Callback> mPendingSends;
private DatagramSocket mSocket; private DatagramSocket mSocket;
private boolean mIsMulticastSocket = false;
private UdpSocketClient(Builder builder) { private UdpSocketClient(Builder builder) {
this.mReceiverListener = builder.receiverListener; 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. * @return boolean true IF the socket is part of a multi-cast group.
*/ */
public boolean isMulticast() { public boolean isMulticast() {
return (mSocket != null && mSocket instanceof MulticastSocket); return mIsMulticastSocket;
} }
/** /**
@ -68,7 +69,7 @@ public final class UdpSocketClient implements UdpReceiverTask.OnDataReceivedList
* binding. * binding.
*/ */
public void bind(Integer port, @Nullable String address) throws IOException { public void bind(Integer port, @Nullable String address) throws IOException {
mSocket = new DatagramSocket(null); mSocket = new MulticastSocket(null);
mReceiverTask = new UdpReceiverTask(); mReceiverTask = new UdpReceiverTask();
@ -101,25 +102,8 @@ public final class UdpSocketClient implements UdpReceiverTask.OnDataReceivedList
throw new IllegalStateException("Socket is not bound."); 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<DatagramSocket, UdpReceiverTask.OnDataReceivedListener>(mSocket, this));
}
((MulticastSocket) mSocket).joinGroup(InetAddress.getByName(address)); ((MulticastSocket) mSocket).joinGroup(InetAddress.getByName(address));
mIsMulticastSocket = true;
} }
/** /**
@ -130,9 +114,8 @@ public final class UdpSocketClient implements UdpReceiverTask.OnDataReceivedList
* @throws IOException * @throws IOException
*/ */
public void dropMembership(String address) throws UnknownHostException, 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;
} }
/** /**

View File

@ -177,22 +177,26 @@ public final class UdpSockets extends ReactContextBaseJavaModule
mMulticastLock.setReferenceCounted(true); mMulticastLock.setReferenceCounted(true);
} }
if (!client.isMulticast()) {
// acquire the multi-cast lock, IF this is the
// first addMembership call for this client.
mMulticastLock.acquire();
}
try { try {
mMulticastLock.acquire();
client.addMembership(multicastAddress); client.addMembership(multicastAddress);
} catch (IllegalStateException ise) { } catch (IllegalStateException ise) {
// an exception occurred // an exception occurred
if (mMulticastLock != null && mMulticastLock.isHeld()) {
mMulticastLock.release();
}
FLog.e(TAG, "addMembership", ise); FLog.e(TAG, "addMembership", ise);
} catch (UnknownHostException uhe) { } catch (UnknownHostException uhe) {
// an exception occurred // an exception occurred
if (mMulticastLock != null && mMulticastLock.isHeld()) {
mMulticastLock.release();
}
FLog.e(TAG, "addMembership", uhe); FLog.e(TAG, "addMembership", uhe);
} catch (IOException ioe) { } catch (IOException ioe) {
// an exception occurred // an exception occurred
if (mMulticastLock != null && mMulticastLock.isHeld()) {
mMulticastLock.release();
}
FLog.e(TAG, "addMembership", ioe); FLog.e(TAG, "addMembership", ioe);
} }
} }
@ -217,6 +221,10 @@ public final class UdpSockets extends ReactContextBaseJavaModule
} catch (IOException ioe) { } catch (IOException ioe) {
// an exception occurred // an exception occurred
FLog.e(TAG, "dropMembership", ioe); FLog.e(TAG, "dropMembership", ioe);
} finally {
if (mMulticastLock != null && mMulticastLock.isHeld()) {
mMulticastLock.release();
}
} }
} }
}.execute(); }.execute();
@ -263,7 +271,7 @@ public final class UdpSockets extends ReactContextBaseJavaModule
return; 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 // drop the multi-cast lock if this is a multi-cast client
mMulticastLock.release(); mMulticastLock.release();
} }