Picking code updated with full basic implementation of message sending and server...
authorimilne <imilne@issues.jalview.org>
Thu, 14 Dec 2006 11:56:17 +0000 (11:56 +0000)
committerimilne <imilne@issues.jalview.org>
Thu, 14 Dec 2006 11:56:17 +0000 (11:56 +0000)
git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@255 be28352e-c001-0410-b1a7-c7978e42abec

src/org/vamsas/client/picking/PickEndPoint.java
src/org/vamsas/client/picking/PickManager.java
src/org/vamsas/client/picking/PickServer.java
src/org/vamsas/client/picking/TestApp.java

index c81b744..7a464f1 100644 (file)
@@ -6,72 +6,96 @@ import java.net.*;
 class PickEndPoint extends Thread\r
 {\r
        private Socket socket;\r
+       private int rPort;\r
        private BufferedWriter os;\r
        private BufferedReader in;\r
+\r
+       private PickManager manager;    \r
        \r
-       // Constructs a new client connection (client->server)\r
-       PickEndPoint()\r
-               throws Exception\r
-       {\r
-               // Attempt to connect...\r
-               // If we fail, wrapper has to attempt to make server instead??\r
-               // Or keep trying until a server exists\r
-               socket = new Socket(InetAddress.getLocalHost(), PickServer.PORT);\r
-               \r
-               createStreams();\r
-       }\r
-       \r
-       // Constructs a new client based on an existing connection (server->client)\r
-       PickEndPoint(Socket s)\r
-               throws IOException\r
+       PickEndPoint(PickManager manager, Socket s)\r
        {\r
+               this.manager = manager;\r
                socket = s;\r
-               createStreams();\r
        }\r
        \r
-       private void createStreams()\r
-               throws IOException\r
+       boolean openConnection()\r
        {\r
-               os = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));\r
-               \r
-               in = new BufferedReader(new InputStreamReader(socket.getInputStream()));\r
+               try\r
+               {\r
+                       // Create the socket if it doesn't already exist\r
+                       if (socket == null)\r
+                               socket = new Socket(InetAddress.getLocalHost(), PickServer.PORT);\r
+                       \r
+                       rPort = socket.getPort();\r
+                       socket.setKeepAlive(true);\r
+                                               \r
+                       // Open the streams for reading/writing\r
+                       os = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));\r
+                       in = new BufferedReader(new InputStreamReader(socket.getInputStream()));\r
                \r
-               start();\r
+                       // Start the thread to listen for incoming messages\r
+                       System.out.println("CLIENT: connection successful to port "\r
+                               + socket.getPort() + " via port " + socket.getLocalPort());\r
+                       start();\r
+                       \r
+                       return true;\r
+               }\r
+               catch (Exception e)\r
+               {\r
+                       System.out.println("CLIENT: connection failed: " + e);\r
+                       return false;\r
+               }\r
        }\r
        \r
-       void send()\r
+       void send(String str)\r
        {\r
                try\r
                {\r
-                       System.out.println("CLIENT: sending message...");\r
-                       os.write("test message: " + (System.currentTimeMillis()));\r
+                       System.out.println("CLIENT: send " + str + " to " + rPort);\r
+                       os.write(str);\r
                        \r
                        // We use a newline to terminate the message\r
                        os.newLine();\r
                        os.flush();\r
-                       System.out.println("CLIENT: message sent");\r
                }\r
                catch (Exception e)\r
                {\r
-                       System.out.println(e);\r
+                       System.out.println("CLIENT: failed to send");\r
+                       \r
+                       // TODO: terminate the connection on a failed send or retry?\r
+                       terminate();\r
                }\r
        }\r
        \r
+       // void receive() (threaded)\r
        public void run()\r
        {\r
-               try {\r
-               while (true)\r
+               try\r
                {\r
-                       String str = in.readLine();\r
-                       \r
-                       System.out.println("CLIENT: READ: " + str);\r
+                       while (true)\r
+                       {\r
+                               String str = in.readLine();                             \r
+                               System.out.println("CLIENT: recv " + str + " from " + rPort);\r
+                               \r
+                               manager.handleMessage(this, str);\r
+                       }\r
+               }\r
+               catch (Exception e)\r
+               {\r
+                       // Means the other end of the connection has (probably died) so we need\r
+                       // terminate this endpoint (if this is server side)\r
+                       System.out.println("CLIENT: read failed: " + e);\r
+                                               \r
+                       terminate();\r
                }\r
        }\r
-       catch (Exception e)\r
+       \r
+       private void terminate()\r
        {\r
-               System.out.println("CLIENT: read fail: " + e);\r
-               // Means the other end of the connection has (probably died) so we need\r
-               // terminate this endpoint (if this is server side)\r
-       }\r
+               try { socket.close(); }\r
+               catch (IOException e) {}\r
+               \r
+               System.out.println("CLIENT: closing connection to port " + socket.getPort());\r
+               manager.removeEndPoint(this);\r
        }\r
 }
\ No newline at end of file
index 6e93955..e4f4445 100644 (file)
@@ -1,5 +1,6 @@
 package org.vamsas.client.picking;\r
 \r
+import java.net.*;\r
 import java.util.*;\r
 \r
 public class PickManager\r
@@ -8,9 +9,99 @@ public class PickManager
        // a way of talking to either:\r
        //  the server - if this is client side (and in which case, the list will only contain one element\r
        //  the other clients - if this is server side\r
-       private LinkedList clients = new LinkedList();\r
+       private LinkedList clients;\r
+       \r
+       private PickServer server;\r
        \r
        public PickManager()\r
        {\r
+               server = new PickServer(this);\r
+               clients = new LinkedList();\r
+               \r
+               new InitializeThread().start();\r
+       }\r
+       \r
+       // Called whenver we try to make a new endpoint<->endpoint connection\r
+       boolean addClientConnection(Socket socket)\r
+       {\r
+               PickEndPoint client = new PickEndPoint(this, socket);\r
+               \r
+               if (client.openConnection())\r
+               {\r
+                       clients.add(client);\r
+                       System.out.println("List now contains " + clients.size() + " client(s)");\r
+                       return true;\r
+               }\r
+               \r
+               return false;\r
+       }\r
+       \r
+       public void sendMessage(String str)\r
+       {\r
+               forwardMessage(null, str);\r
+       }\r
+       \r
+       // Forwards (or sends) a message\r
+       // When the server receives a message, it will be resent to all clients,\r
+       // but *not* to the client that sent it out in the first place!\r
+       private void forwardMessage(PickEndPoint origin, String str)\r
+       {\r
+               ListIterator itor = clients.listIterator();\r
+               while (itor.hasNext())\r
+               {\r
+                       PickEndPoint client = (PickEndPoint) itor.next();\r
+                       \r
+                       if (client != origin)\r
+                               client.send(str);\r
+               }\r
+       }\r
+       \r
+       // Called by the endpoint code when a message is received\r
+       // The manager has to:\r
+       //  a) hand message to VAMSAS app\r
+       //  b) forward it to other clients if we're the server\r
+       void handleMessage(PickEndPoint origin, String str)\r
+       {\r
+               if (server.isServer())\r
+                       forwardMessage(origin, str);\r
+               \r
+               // TODO: pass message to VAMSAS API\r
+       }\r
+       \r
+       void removeEndPoint(PickEndPoint client)\r
+       {\r
+               clients.remove(client);\r
+               System.out.println("List now contains " + clients.size() + " client(s)");\r
+               \r
+               // If there's no endpoints left, then we've lost all connections and\r
+               // need to reinitialize\r
+               if (clients.size() == 0)\r
+                       new InitializeThread().start();\r
+       }\r
+       \r
+       private class InitializeThread extends Thread\r
+       {\r
+               public void run()\r
+               {\r
+                       System.out.println("Initializing connection...");\r
+                       boolean connected = false;\r
+                       \r
+                       // Loop until we can get a connection (one way or the other)\r
+                       while (!connected)\r
+                       {\r
+                               // Sleep for a rnd time so we don't end up with all the VAMSAS\r
+                               // apps trying to initialize servers at the same time\r
+                               try { Thread.sleep((int)Math.random()); }\r
+                               catch (InterruptedException e) {}\r
+                                       \r
+                               // Attempt to open the server port...\r
+                               if (server.isServer() || server.createServer())\r
+                                       connected = true;\r
+\r
+                               // If it fails, then attempt to make a client connection...\r
+                               else if (addClientConnection(null))\r
+                                       connected = true;\r
+                       }\r
+               }\r
        }\r
 }
\ No newline at end of file
index f483b05..be18c67 100644 (file)
@@ -8,11 +8,18 @@ class PickServer extends Thread
        static final int PORT = 53782;\r
        \r
        private ServerSocket serverSocket;\r
+       private boolean isServer = false;\r
        \r
-       PickServer()\r
+       private PickManager manager;\r
+       \r
+       PickServer(PickManager manager)\r
        {\r
+               this.manager = manager;\r
        }\r
        \r
+       boolean isServer()\r
+               { return isServer; }\r
+       \r
        boolean createServer()\r
        {\r
                try\r
@@ -20,31 +27,29 @@ class PickServer extends Thread
                        serverSocket = new ServerSocket(PORT);\r
                        start();                        \r
                        \r
-                       return true;\r
+                       return isServer = true;\r
                }\r
                catch (IOException e)\r
                {\r
                        // If we fail, just assume another app already has the port\r
-                       System.out.println(e);\r
+                       System.out.println("SERVER: " + e);\r
                        return false;\r
                }\r
        }\r
        \r
        public void run()\r
        {\r
-               System.out.println("SERVER: listening...");\r
+               System.out.println("SERVER: listening on " + PORT + " - SERVER");\r
                \r
                // Loop forever, accepting connectons from other clients\r
                while (true)\r
                {\r
                        try\r
                        {\r
-                               Socket socket = serverSocket.accept();\r
+                               Socket socket = serverSocket.accept();                          \r
+                               System.out.println("SERVER: connection detected");\r
                                \r
-                               System.out.println("SERVER: connection made, spawning pipe...");\r
-\r
-                               // Do something with the socket...\r
-                               new PickEndPoint(socket);\r
+                               manager.addClientConnection(socket);\r
                        }\r
                        catch (IOException e) {}\r
                }\r
index 3e89ee8..507daea 100644 (file)
@@ -7,16 +7,17 @@ public class TestApp
        {\r
                TestApp app = new TestApp();\r
                \r
-               PickServer server = new PickServer();\r
+               PickManager manager = new PickManager();\r
                \r
-               \r
-               if (server.createServer() == false)\r
-               {\r
-                       PickEndPoint client = new PickEndPoint();\r
+               // Send 5 test messages...\r
+//             for (int i = 0; i < 5; i++)\r
+               while (true)\r
+               {                       \r
+                       try { Thread.sleep((int) (Math.random()*20000)); }\r
+                       catch (InterruptedException e) {}\r
                        \r
-                       for (int i = 0; i < 10; i++)\r
-                               client.send();\r
-//                     client.send();\r
+                       int rnd = (int) (Math.random()*100);\r
+                       manager.sendMessage("" + rnd);\r
                }\r
        }\r
        \r