/** * UdpReceiverTask.java * react-native-udp * * Created by Andy Prock on 9/24/15. */ package com.tradle.react; import android.os.AsyncTask; import android.util.Base64; import android.util.Pair; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * This is a specialized AsyncTask that receives data from a socket in the background, and * notifies it's listener when data is received. This is not threadsafe, the listener * should handle synchronicity. */ public class UdpReceiverTask extends AsyncTask<Pair<DatagramSocket, UdpReceiverTask.OnDataReceivedListener>, Void, Void> { private static final String TAG = "UdpReceiverTask"; private static final int MAX_UDP_DATAGRAM_LEN = 0xffff; /** * An infinite loop to block and read data from the socket. */ @Override protected Void doInBackground(Pair<DatagramSocket, UdpReceiverTask.OnDataReceivedListener>... params) { if (params.length > 1) { throw new IllegalArgumentException("This task is only for a single socket/listener pair."); } DatagramSocket socket = params[0].first; OnDataReceivedListener receiverListener = params[0].second; final byte[] buffer = new byte[MAX_UDP_DATAGRAM_LEN]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); while (!isCancelled()) { try { socket.receive(packet); final InetAddress address = packet.getAddress(); final String base64Data = Base64.encodeToString(packet.getData(), packet.getOffset(), packet.getLength(), Base64.NO_WRAP); receiverListener.didReceiveData(base64Data, address.getHostAddress(), packet.getPort()); } catch (IOException ioe) { if (receiverListener != null) { receiverListener.didReceiveError(ioe.getMessage()); } this.cancel(false); } catch (RuntimeException rte) { if (receiverListener != null) { receiverListener.didReceiveRuntimeException(rte); } this.cancel(false); } } return null; } /** * Listener interface for receive events. */ public interface OnDataReceivedListener { void didReceiveData(String data, String host, int port); void didReceiveError(String message); void didReceiveRuntimeException(RuntimeException exception); } }