View Javadoc

1   /*
2    * Created on 17 Nov 2007
3    *
4    */
5   package org.sourceforge.jemmrpc.server;
6   
7   import java.net.Socket;
8   import java.util.Map;
9   import java.util.concurrent.CountDownLatch;
10  import java.util.concurrent.ExecutorService;
11  
12  import org.apache.log4j.Logger;
13  import org.sourceforge.jemmrpc.shared.RPCHandler;
14  import org.sourceforge.jemmrpc.shared.RPCHandlerListener;
15  
16  /**
17   * ServerThread is used by RPCServer for handling individual client connections.
18   *
19   * @author Rory Graves
20   */
21  public class ServerThread implements RPCHandlerListener
22  {
23      protected static final Logger LOG = Logger.getLogger(ServerThread.class);
24  
25      protected final CountDownLatch shutdownLatch = new CountDownLatch(1);
26  
27      protected final ClientId clientId;
28  
29      protected final RPCServer server;
30  
31      protected final RPCHandler rpcHandler;
32  
33      protected final Socket socket;
34  
35      protected volatile boolean connected;
36  
37      /**
38       * Creates a server thread to handle a specific client connection.
39       *
40       * @param fServer The server instance this client belongs to
41       * @param fSocket The client socket
42       * @param fClientId The server assigned client id;
43       * @param fOfferedIfs The interfaces offered to the client by the server
44       * @param fThreadPool The threadpool to use for servicing requests
45       */
46      public ServerThread(RPCServer fServer, Socket fSocket, ClientId fClientId,
47              Map<Class<?>, Object> fOfferedIfs, ExecutorService fThreadPool)
48      {
49          this.server = fServer;
50          this.socket = fSocket;
51          this.clientId = fClientId;
52  
53          rpcHandler = new RPCHandler(false, fSocket, fOfferedIfs, fThreadPool, fClientId);
54          rpcHandler.setHandlerListener(this);
55      }
56  
57      /**
58       * Start the server thread, initialising the connection and listening to client requests.
59       */
60      public void start()
61      {
62          connected = true;
63          server.notifyNewClient(clientId, socket.getInetAddress().toString(), socket
64                  .getPort());
65          rpcHandler.start();
66      }
67  
68      /**
69       * Notification that the connection has been closed.
70       */
71      public void connectionTerminated()
72      {
73          if (connected)
74              shutdown();
75      }
76  
77      /**
78       * Shutdown the thread by closing its socket connection.
79       */
80      public void shutdown()
81      {
82          if (connected)
83          {
84              connected = false;
85              rpcHandler.close();
86              server.clientDisconnected(clientId);
87              shutdownLatch.countDown();
88          }
89      }
90  
91      /**
92       * Utility method to allow a thread to wait for this thread to have completely terminated. This
93       * method will return immediately if the thread is already stopped, otherwise it will wait until
94       * all shutdown actions have completed before returning.
95       */
96      public void waitForShutdown()
97      {
98          try
99          {
100             shutdownLatch.await();
101         }
102         catch (final InterruptedException e)
103         {
104             // do nothing
105         }
106     }
107 
108     /**
109      * Gets the proxy for the given client interface.
110      *
111      * @param ifClass The requesting interface implementation.
112      * @return A proxy that implements the interface 'ifClass'
113      */
114     public Object getClientIF(Class<?> ifClass)
115     {
116         return rpcHandler.getRemoteIF(ifClass);
117     }
118 }