1 package uk.ac.vamsas.client.picking;
\r
5 import java.util.logging.*;
\r
8 * Manager class that maintains a list of connected clients in addition to
\r
9 * attempting to run a server to listen for client connections. If the server
\r
10 * initialization fails, then an attempt to connect (as a client) to another JVM
\r
11 * that is already a server happens instead.
\r
13 public class PickManager
\r
15 private static Logger logger = Logger.getLogger("uk.ac.vamsas.client.picking");
\r
17 // Maintains a list of client communication objects - each object represents
\r
18 // a way of talking to either:
\r
19 // the server - if this is client side (and in which case, the list will only contain one element
\r
20 // the other clients - if this is server side
\r
21 private LinkedList clients;
\r
23 private PickServer server;
\r
26 * Constructs a new PickManager. This method will return immediately, while
\r
27 * a looping thread runs that attempts to run the server or connect to an
\r
30 public PickManager()
\r
32 server = new PickServer(this);
\r
33 clients = new LinkedList();
\r
35 new InitializeThread().start();
\r
39 * Attempts to establish a connection between two client endpoints. This
\r
40 * method is called in two ways: 1) by the server when it receives a remote
\r
41 * request (in which case the socket will already be established) and 2) by
\r
42 * a client that is attempting to connect *to* the server.
\r
43 * @param socket a socket endpoint for the connection
\r
44 * @return true if the connection is successfully, false otherwise
\r
46 boolean addEndPoint(Socket socket)
\r
48 PickEndPoint client = new PickEndPoint(this, socket);
\r
50 if (client.openConnection())
\r
52 clients.add(client);
\r
53 logger.fine("List now contains " + clients.size() + " client(s)");
\r
61 * Sends a message to other clients.
\r
62 * @param str the message to send
\r
64 public void sendMessage(String str)
\r
66 forwardMessage(null, str);
\r
70 * Forwards (or sends) a message. When the server (client A) receives a
\r
71 * message from client B, it must also forward it to clients C and D (etc),
\r
72 * but mustn't forward it *back* to client B.
\r
73 * @param origin the client endpoint that received the message (will be null
\r
74 * if the message originates from this instance
\r
75 * @param str the message to send
\r
77 private void forwardMessage(PickEndPoint origin, String str)
\r
79 ListIterator itor = clients.listIterator();
\r
80 while (itor.hasNext())
\r
82 PickEndPoint client = (PickEndPoint) itor.next();
\r
84 if (client != origin)
\r
90 * Handles a received message. If the manager is running in server mode,
\r
91 * then it must ensure the message is also forwarded to the other clients.
\r
92 * @param origin the client endpoint that received the message
\r
93 * @str the message that was received
\r
95 void handleMessage(PickEndPoint origin, String str)
\r
97 if (server.isServer())
\r
98 forwardMessage(origin, str);
\r
100 // TODO: pass message to VAMSAS API
\r
104 * Removes a client connection from the list when its connection is no
\r
106 * @param client the client endpoint to remove
\r
108 void removeEndPoint(PickEndPoint client)
\r
110 clients.remove(client);
\r
111 logger.fine("List now contains " + clients.size() + " client(s)");
\r
113 // If there's no endpoints left, then we've lost all connections and
\r
114 // need to reinitialize
\r
115 if (clients.size() == 0)
\r
116 new InitializeThread().start();
\r
120 * Thread extension class to handle the actual initialization
\r
122 private class InitializeThread extends Thread
\r
126 logger.fine("Initializing connection...");
\r
127 boolean connected = false;
\r
129 // Loop until we can get a connection (one way or the other)
\r
132 // Sleep for a rnd time so we don't end up with all the VAMSAS
\r
133 // apps trying to initialize servers at the same time
\r
134 try { Thread.sleep((int)Math.random()); }
\r
135 catch (InterruptedException e) {}
\r
137 // Attempt to open the server port...
\r
138 if (server.isServer() || server.createServer())
\r
141 // If it fails, then attempt to make a client connection...
\r
142 else if (addEndPoint(null))
\r