首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

多線程環境下透過 WebSocket 推送資料到前端的實作指南

     編輯:程式設計疑難解答

問題背景

系統中有多個查詢線程分別輪詢不同設備獲取資料,當使用者開啟網頁時會自動建立 WebSocket 連線。查詢線程與 WebSocket 連線管理屬於不同執行緒,如何在查詢線程中呼叫 WebSocket 的 send 方法將即時資料推送給前端?

核心架構:Session 註冊表

採用「生產者-消費者」模式,後端維護一個線程安全的 Map<String, Session>(或 ConcurrentHashMap),Key 為使用者唯一標識(如 userId、deviceId),Value 為對應的 javax.websocket.Session 物件。

關鍵步驟

  1. 連線建立時註冊:@OnOpen 方法中將 Session 放入 Map。
  2. 連線關閉時移除:@OnClose / @OnError 移除 Map 中對應條目,防止記憶體洩漏。
  3. 查詢線程推送資料:查詢到資料後,遍歷 Map 或依特定 Key 取得 Session,呼叫 session.getBasicRemote().sendText(json) 或 sendBinary。

程式碼範例

@ServerEndpoint("/websocket/{userId}")
@Component // Spring 管理
public class DeviceWebSocket {

    private static final ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        sessions.put(userId, session);
    }

    @OnClose
    public void onClose(@PathParam("userId") String userId) {
        sessions.remove(userId);
    }

    /** 供查詢線程呼叫的靜態推送方法 */
    public static void pushData(String userId, String jsonPayload) {
        Session session = sessions.get(userId);
        if (session != null && session.isOpen()) {
            try {
                session.getBasicRemote().sendText(jsonPayload);
            } catch (IOException e) {
                log.error("WebSocket 推送失敗: {}", e.getMessage());
                sessions.remove(userId); // 發送失敗視為連線異常,清理
            }
        }
    }
}

查詢線程中調用

// 查詢線程內部
String payload = buildJson(deviceId, sensorData);
DeviceWebSocket.pushData(targetUserId, payload);

進階考量

  • 廣播場景:若需推送給所有線上使用者,可 sessions.values().forEach(s -> ...),注意效能與背壓。
  • 叢集部署:單機 Map 無法跨節點共享,需引入 Redis Pub/Sub、Kafka 或 Spring Cloud Stream 實現分散式推送。
  • 心跳機制:定期發送 Ping/Pong 檢測死連線,配合 @OnError 清理殭屍 Session。
  • 非同步發送:高併發下建議使用 session.getAsyncRemote() 避免阻塞查詢線程。

總結

核心在於「共享 Session 註冊表」+「線程安全存取」。查詢線程只需持有使用者標識,即可隨時從註冊表取得 Session 並推送資料,實現真正的伺服器主動推送。

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