首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Socket 聊天室客戶端深度解析:架構、心跳、訊息分發與 UI 解耦

     編輯:Java 相關知識

本文基於一個完整的 Java Swing Socket 聊天室客戶端,從通訊模組與UI 模組兩大維度,深度剖析其多執行緒架構、心跳機制、訊息路由分發、以及 UI 與業務邏輯的解耦設計,附完整代碼結構與關鍵類別說明。

整體架構圖解

客戶端通訊模組類圖

UI 模組類圖

一、通訊模組核心設計

1. 入口類:Client

  • 持有 Socket、固定大小 2 的 ExecutorService (接收 + 心跳)
  • 注入 Callback 介面,實現訊息處理邏輯的可插拔
  • start() 啟動 ReceiveListener;keepAlive() 啟動 KeepAliveDog

2. 心跳發送:KeepAliveDog

  • 每 KEEP_ALIVE_PERIOD 秒發送 AliveMessage (JSON 序列化)
  • 使用 PrintWriter 寫入 Socket 輸出流,flush() 確保送達
  • 若 Socket 關閉自動結束迴圈

3. 訊息接收:ReceiveListener

  • 阻塞式讀取 BufferedReader,累積完整行
  • 收到訊息 → LoggerUtil.trach 記錄 → callback.doWork() 分發
  • 若為 FILE 類型,Thread.sleep(MESSAGE_PERIOD) 讓位給檔案流讀取

4. 回調機制:Callback & DefaultCallback

  • Callback 單一方法 doWork(Socket, Object),業務邏輯完全外置
  • DefaultCallback 處理三類訊息:
    • CHAT:路由至對應分頁 JTextArea 顯示
    • FILE:直接寫入 CLIENT_RECEIVE_DIR,未經使用者確認 (可改進)
    • RETURN:根據 Key 分發給對應 Handler

5. 處理器鏈:Handler & HF (Handler Factory)

  • Handler 介面單一方法 handle(Object)
  • HF.getHandler(key) 簡易工廠回傳具體實作:LoginHdl、RegisterHdl、ListUserHdl、NotifyHdl、TipHdl
  • 各 Handler 操作 UI 元件 (透過 Router 取得) 完成登入跳轉、用戶列表刷新、通知彈窗等

6. 單例持有:ClientHolder

靜態持有 Client 實例,供全域存取 (如 Action 發送訊息)。

二、UI 模組:View/Router/Action 三層解耦

1. 統一介面:View

public interface View {
  View create();           // 延遲初始化
  Container container();   // 給 JOptionPane 用
  JComponent getComponent(String key); // 供 Handler 取得元件
  void display();          // setVisible(true)
  void trash();            // dispose()
}

2. 路由器:Router

  • 單例 Map<String, View> 快取已建立視圖
  • getView(Class) 反射實例化並快取

3. 兩大視圖實作

  • RegisterAndLoginView:帳密輸入、註冊/登入/離開按鈕、Enter 鍵觸發登入
  • ChatRoomView:BorderLayout 中央 JTabbedPane (聊天分頁)、東側 JList (線上用戶)、底部輸入區 (文字/檔案/發送)

4. Action 處理使用者事件

  • RegisterAndLoginAction:組裝 RegisterMessage/LoginMessage 經 SendHelper 發送
  • ChatRoomAction:處理發送文字、上傳檔案 (非廣播模式)

5. 聊天分頁快取:ResultHolder / ResultWrapper

  • ResultWrapper 封裝 JScrollPane + JTextArea
  • ResultHolder 以 Map<String, ResultWrapper> 快取,鍵為對方用戶名

三、啟動入口

public class NiloayChat {
  public static void main(String[] args) {
    View loginView = Router.getView(RegisterAndLoginView.class).create();
    loginView.display();
    try {
      Client client = new Client(new DefaultCallback());
      client.start();
      ClientHolder.setClient(client);
    } catch (IOException e) {
      JOptionPane.showMessageDialog(loginView.container(), e.getMessage());
    }
  }
}

四、可改進方向

  1. 心跳改用 ScheduledExecutorService 更精準
  2. 檔案接收加入使用者確認對話框
  3. 訊息序列化統一改用 Protobuf/MessagePack 提升效能
  4. UI 採用 JavaFX 或 Web 技術替代 Swing
  5. 引入 TLS/SSL 加密傳輸

總結

該客戶端展示了經典的「固定執行緒池 + 回調分發 + 介面導向 UI」架構。通訊層與 UI 層透過 Callback/Handler/Router 徹底解耦,擴充新訊息類型只需新增 Handler 並註冊至 HF,符合開放封閉原則。代碼結構清晰,適合作為 Java Socket 程式設計的進階學習範本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved