+++ /dev/null
-package org.vamsas.client.picking;\r
-\r
-import java.io.*;\r
-import java.net.*;\r
-\r
-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
- PickEndPoint(PickManager manager, Socket s)\r
- {\r
- this.manager = manager;\r
- socket = s;\r
- }\r
- \r
- boolean openConnection()\r
- {\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 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(String str)\r
- {\r
- try\r
- {\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
- }\r
- catch (Exception e)\r
- {\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
- {\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
- \r
- private void terminate()\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
+++ /dev/null
-package org.vamsas.client.picking;\r
-\r
-import java.net.*;\r
-import java.util.*;\r
-import java.util.logging.*;\r
-\r
-/**\r
- * Manager class that maintains a list of connected clients in addition to\r
- * attempting to run a server to listen for client connections. If the server\r
- * initialization fails, then an attempt to connect (as a client) to another JVM\r
- * that is already a server happens instead.\r
- */\r
-public class PickManager\r
-{\r
- private static Logger logger = Logger.getLogger("org.vamsas.client.picking");\r
- \r
- // Maintains a list of client communication objects - each object represents\r
- // 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;\r
- \r
- private PickServer server;\r
- \r
- /**\r
- * Constructs a new PickManager. This method will return immediately, while\r
- * a looping thread runs that attempts to run the server or connect to an\r
- * existing server.\r
- */\r
- public PickManager()\r
- {\r
- server = new PickServer(this);\r
- clients = new LinkedList();\r
- \r
- new InitializeThread().start();\r
- }\r
- \r
- /**\r
- * Attempts to establish a connection between two client endpoints. This\r
- * method is called in two ways: 1) by the server when it receives a remote\r
- * request (in which case the socket will already be established) and 2) by\r
- * a client that is attempting to connect *to* the server.\r
- * @param socket a socket endpoint for the connection\r
- * @return true if the connection is successfully, false otherwise\r
- */\r
- boolean addEndPoint(Socket socket)\r
- {\r
- PickEndPoint client = new PickEndPoint(this, socket);\r
- \r
- if (client.openConnection())\r
- {\r
- clients.add(client);\r
- logger.fine("List now contains " + clients.size() + " client(s)");\r
- return true;\r
- }\r
- \r
- return false;\r
- }\r
- \r
- /**\r
- * Sends a message to other clients.\r
- * @param str the message to send\r
- */\r
- public void sendMessage(String str)\r
- {\r
- forwardMessage(null, str);\r
- }\r
- \r
- /**\r
- * Forwards (or sends) a message. When the server (client A) receives a\r
- * message from client B, it must also forward it to clients C and D (etc),\r
- * but mustn't forward it *back* to client B.\r
- * @param origin the client endpoint that received the message (will be null\r
- * if the message originates from this instance\r
- * @param str the message to send\r
- */\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
- /**\r
- * Handles a received message. If the manager is running in server mode,\r
- * then it must ensure the message is also forwarded to the other clients.\r
- * @param origin the client endpoint that received the message\r
- * @str the message that was received\r
- */\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
- /**\r
- * Removes a client connection from the list when its connection is no\r
- * longer valid.\r
- * @param client the client endpoint to remove\r
- */\r
- void removeEndPoint(PickEndPoint client)\r
- {\r
- clients.remove(client);\r
- logger.fine("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
- /**\r
- * Thread extension class to handle the actual initialization\r
- */\r
- private class InitializeThread extends Thread\r
- {\r
- public void run()\r
- {\r
- logger.fine("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 (addEndPoint(null))\r
- connected = true;\r
- }\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-package org.vamsas.client.picking;\r
-\r
-import java.io.*;\r
-import java.net.*;\r
-import java.util.logging.*;\r
-\r
-/**\r
- * Server class that listens for incoming connections on a predefined port.\r
- */\r
-class PickServer extends Thread\r
-{\r
- private static Logger logger = Logger.getLogger("org.vamsas.client.picking");\r
- \r
- // The port number we'll listen on\r
- static final int PORT = 53782;\r
- \r
- private ServerSocket serverSocket;\r
- // Set to true once the server is established\r
- private boolean isServer = false;\r
- \r
- private PickManager manager;\r
- \r
- /**\r
- * Constructs a new instance of the server (but doesn't start it).\r
- * @param manager a reference to the pick manager that owns this server\r
- */\r
- PickServer(PickManager manager)\r
- {\r
- this.manager = manager;\r
- }\r
- \r
- /**\r
- * Returns true if this server instance is running.\r
- * Return true if this server instance is running\r
- */\r
- boolean isServer()\r
- { return isServer; }\r
- \r
- /**\r
- * Attempts to create the server by opening a server socket on the port.\r
- * @return true if the server was created; false otherwise\r
- */\r
- boolean createServer()\r
- {\r
- try\r
- {\r
- serverSocket = new ServerSocket(PORT);\r
- start(); \r
- \r
- return isServer = true;\r
- }\r
- catch (IOException e)\r
- {\r
- logger.info("SERVER: " + e);\r
- return false;\r
- }\r
- }\r
- \r
- /**\r
- * Thread listening method - loops indefinitely listening for connections.\r
- * When one is received, the socket object is passed to the manager so it\r
- * can make a full client connection for further comms.\r
- */\r
- public void run()\r
- {\r
- logger.fine("SERVER: listening on " + PORT + " - SERVER");\r
- \r
- // Loop forever, accepting connectons from other clients\r
- // TODO: add in the ability to terminate the server if a VAMSAS session\r
- // is ended\r
- while (true)\r
- {\r
- try\r
- {\r
- Socket socket = serverSocket.accept(); \r
- logger.fine("SERVER: connection detected");\r
- \r
- manager.addEndPoint(socket);\r
- }\r
- catch (IOException e) {}\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-package org.vamsas.client.picking;\r
-\r
-import java.util.logging.*;\r
-\r
-public class TestApp\r
-{\r
- private static Logger logger = Logger.getLogger("org.vamsas.client.picking");\r
- \r
- public static void main(String[] args)\r
- throws Exception\r
- {\r
-// logger.setLevel(Level.INFO);\r
- \r
- TestApp app = new TestApp();\r
- \r
- PickManager manager = new PickManager();\r
- \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
- int rnd = (int) (Math.random()*100);\r
- manager.sendMessage("" + rnd);\r
- }\r
- }\r
- \r
- public TestApp()\r
- {\r
- }\r
-}
\ No newline at end of file