2012-04-07 171 views
0

我開發了一個java swing客戶端 - 服務器應用程序。服務器有許多服務,如數據庫服務,緩存服務和客戶服務對客戶的談話。在Socket中處理多個客戶端

客戶服務打開一個端口上的插座並監聽傳入的連接。它爲每個客戶端連接生成一個新線程,創建一個會話並讀取傳入的序列化對象。它維護這個會話(使線程保持活動狀態)直到客戶端發出'CLOSE_SESSION'命令。

什麼,我想知道的是,如果它的正確產卵爲每一個新的客戶端插槽會話一個新的線程。謝謝。

我的客戶服務代碼如下所示。

代碼來創建服務器套接字:

  try { 
       ServerSocket socket = new ServerSocket(serverPort); 
       Socket listener = socket.accept(); 

       Thread client = new Thread(new ClientHandler(listener)); 
       client.start(); 

      } catch (IOException ex) { 
       log.error(new Throwable(ex)); 
      } 

代碼生成新線程爲每個客戶

class ClientHandler implements Runnable { 

private static Logger log = Logger.getLogger(ClientHandler.class); 

private Socket listener; 

public ClientHandler(Socket listener) { 
    this.listener = listener; 
} 

public void run() { 
    try { 
     ObjectInputStream inStream = new ObjectInputStream(
       listener.getInputStream()); 
     try { 
      ServiceRequestResponse request = (ServiceRequestResponse) inStream 
        .readObject(); 
      if (request != null && request.getServiceCommand() != null) { 

       ServiceCommand command = request.getServiceCommand(); 
       log.debug("command : " + command.getCommand()); 
       log.debug("is session alive? " + request.isAlive()); 
       log.debug("ServiceCommand.CREATE_SESSION : " 
         + ServiceCommand.CREATE_SESSION.getCommand()); 
       if (!request.isAlive() 
         && command.getCommand().equals(
           ServiceCommand.CREATE_SESSION.getCommand())) { 
        // No session yet, and service command issued is login. 
        // Call login service, check credentials and create 
        // session. 
        request.setSessionId(UUID.randomUUID()); 
        log.debug("Created user session with id : " 
          + request.getSessionId()); 
       } else { 
        if (command.getCommand().equals(
          ServiceCommand.CLOSE_SESSION)) { 
         // Close session and do clean up here 
        } 
        // Here session is alive. 
        while (!ServiceCommand.CLOSE_SESSION.equals(command 
          .getCommand())) { 
         // Read the service command from the request 
         // response and 
         // Hand it over to the appropriate handler. 
        } 

       } 

      } 

     } catch (ClassNotFoundException ex) { 
      log.error(new Throwable(ex)); 
     } 

    } catch (IOException ex) { 

    } 

} 

}

+0

您還應該(一)在該循環的底部捕捉EOFException類; (b)記錄您在那裏捕獲的任何其他IOException;和(c)在finally {}塊中關閉套接字。 – EJP 2012-04-07 06:29:49

回答

3

如果您的客戶端會話請求能持續多久則線程per-連接是一個好的解決方案。

替代品有:

  • 使用NIO;
  • 如果客戶端請求很短,則使用線程池。
+0

線程池聽起來像個好主意,但是如何在這種情況下維護sessionid?由於它是一個池,每個線程都有一個關聯的sessionid,它將被重用。我想保持sessionid唯一。 – sachinrahulsourav 2012-04-07 05:58:56

+0

可以將會話上下文關聯到客戶端套接字,例如,將客戶端的套接字作爲關鍵字的映射。或者,如果請求不頻繁,您可以每次關閉套接字。這取決於你的要求。 – dash1e 2012-04-07 06:01:44