1 package com.tirsen.nanning.samples.rmi; 2 3 import java.io.IOException ; 4 import java.net.InetAddress ; 5 import java.net.ServerSocket ; 6 import java.net.Socket ; 7 import java.net.SocketTimeoutException ; 8 import java.security.PrivilegedAction ; 9 import java.util.HashSet ; 10 11 import javax.security.auth.Subject ; 12 13 import com.tirsen.nanning.AspectFactory; 14 import EDU.oswego.cs.dl.util.concurrent.PooledExecutor; 15 import org.apache.commons.logging.Log; 16 import org.apache.commons.logging.LogFactory; 17 18 public class SocketRemoteCallServer { 19 private static final Log logger = LogFactory.getLog(SocketRemoteCallServer.class); 20 21 private RemoteCallServer remoteCallServer; 22 private int port; 23 private ServerSocket serverSocket; 24 private PooledExecutor threadPool; 25 private int threadPoolSize = 5; 26 private boolean doStop; 27 private Thread serverThread; 28 public static final int SERVER_SOCKET_TIMEOUT = 1000; 29 private SocketConnectionManager connectionManager; 30 31 public void start() { 32 try { 33 assert port != 0 : "port not specified"; 34 logger.info("starting RMI-server on port " + port); 35 serverSocket = new ServerSocket (port); 36 connectionManager = new SocketConnectionManager(InetAddress.getLocalHost().getCanonicalHostName(), port); 37 remoteCallServer = new RemoteCallServer(connectionManager); 38 serverSocket.setSoTimeout(SERVER_SOCKET_TIMEOUT); 39 threadPool = new PooledExecutor(threadPoolSize); 40 41 serverThread = new Thread (new Runnable () { 42 public void run() { 43 try { 44 while (!doStop) { 45 try { 46 Socket socket = serverSocket.accept(); 47 48 threadPool.execute(new SocketCallProcessor(socket)); 49 50 } catch (SocketTimeoutException ignore) { 51 } catch (InterruptedException ignore) { 52 } catch (IOException e) { 53 logger.error("error accepting call", e); 54 } 55 } 56 } finally { 57 try { 58 serverSocket.close(); 59 } catch (IOException e) { 60 logger.warn("could not close server", e); 61 } 62 } 63 } 64 }); 65 serverThread.start(); 66 } catch (IOException e) { 67 throw new RuntimeException (e); 68 } 69 } 70 71 public void setPort(int port) { 72 this.port = port; 73 } 74 75 public void stop() { 76 if (serverThread == null && serverSocket == null) { 77 return; 78 } 79 80 doStop = true; 81 try { 82 serverThread.join(SERVER_SOCKET_TIMEOUT + 1); 83 serverThread = null; 84 } catch (InterruptedException e) { 85 logger.warn("could not stop server properly", e); 87 } 89 90 try { 91 serverSocket.close(); 92 serverSocket = null; 93 } catch (IOException e) { 94 logger.warn("could not stop server properly", e); 96 } 98 } 99 100 public void bind(String name, Object object) { 101 remoteCallServer.bind(name, object); 102 } 103 104 public void reset() { 105 remoteCallServer.reset(); 106 } 107 108 public void setAspectFactory(AspectFactory aspectFactory) { 109 remoteCallServer.setAspectFactory(aspectFactory); 110 } 111 112 public boolean isStarted() { 113 return serverSocket != null || serverThread != null; 114 } 115 116 protected class SocketCallProcessor implements Runnable { 117 private final Socket socket; 118 119 public SocketCallProcessor(Socket socket) { 120 this.socket = socket; 121 } 122 123 public void run() { 124 Subject.doAs(new Subject (true, new HashSet (), new HashSet (), new HashSet ()), new PrivilegedAction () { 126 public Object run() { 127 try { 128 remoteCallServer.processCall(socket.getInputStream(), socket.getOutputStream()); 129 } catch (IOException e) { 130 logger.error("error communicating with client", e); 131 } finally { 132 try { 133 socket.close(); 134 } catch (IOException e) { 135 logger.error("error closing socket", e); 136 } 137 } 138 return null; 139 } 140 }); 141 } 142 } 143 } 144 | Popular Tags |