libs.net: complete network functionality
[WeStealzYourDataz.git] / src / uk / ac / ntu / n0521366 / wsyd / libs / net / NetworkServerUDP.java
index 90ca8e6..fda95b5 100644 (file)
@@ -31,6 +31,7 @@ import java.net.DatagramSocket;
 import java.net.DatagramPacket;
 import java.net.SocketException;
 import java.net.SocketTimeoutException;
+import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.logging.LogRecord;
@@ -53,7 +54,15 @@ public class NetworkServerUDP extends NetworkServerAbstract {
      * Maximum size of UDP packet payload
      */
     public static final int UDP_PAYLOAD_SIZE_MAX =  65507;
-    
+
+    /**
+     * Thread safe First In, First Out Queue of NetworkMessage objects waiting to be sent.
+     * 
+     * Allows the Owner Thread to submit new messages for sending that the Worker Thread
+     * can safely access.
+     */
+    protected ConcurrentLinkedQueue<NetworkMessage> _sendMessageQueue = new ConcurrentLinkedQueue<>();
+   
     /**
      * Construct the server with a Logger.
      * 
@@ -243,6 +252,19 @@ public class NetworkServerUDP extends NetworkServerAbstract {
         return result;
     }
 
+     /**
+     * Removes a message from the queue of pending messages.
+     *
+     * This method is called on the Worker Thread by the doInBackground() main loop.
+     *
+     * @return a message to be sent
+     */
+    @Override
+    protected NetworkMessage sendMessage() {
+        return this._sendMessageQueue.poll();
+    }
+    
+    
     /* XXX: Methods below here all execute on the GUI Event Dispatch Thread */
     
     /**
@@ -254,4 +276,35 @@ public class NetworkServerUDP extends NetworkServerAbstract {
     protected  void done() {
         // TODO: done() implement any clean-up after doInBackground() has returned
     }
+
+    /**
+     * Adds a message to the queue of pending messages.
+     * 
+     * This method will usually be called from the Owner Thread.
+     * 
+     * @param message to be sent
+     * @return true if the message was added to the queue
+     * @throws IllegalArgumentException if the target does not exist in the serviceToHost mapping
+     */
+    public boolean queueMessage(NetworkMessage message) throws IllegalArgumentException {
+        boolean result = false;
+        if (message != null) {
+            // ensure the target is set and is a valid service
+            String target = message.getTarget();
+            if (target == null)
+                throw new IllegalArgumentException("target cannot be null");
+            if(!_serviceToHostMap.isServiceValid(target))
+                throw new IllegalArgumentException("target service does not exist: " + target);
+            
+            NetworkMessage temp;
+            try { // make a deep clone of the message
+                temp = NetworkMessage.clone(message);
+                result = this._sendMessageQueue.add(temp);
+            } catch (CloneNotSupportedException e) {
+                // TODO: queueMessage() log CloneNotSupportedException
+                e.printStackTrace();
+            }
+        }
+        return result;
+    }    
 }