WebSocket通訊
WebSocket 是一種全雙工的通訊協議,它允許在客戶端和伺服器之間建立持久的雙向通訊通道。與傳統的 HTTP 協議不同,WebSocket 允許客戶端和伺服器之間實時傳遞資料,而無需頻繁建立連線,從而減少了通訊的開銷和延遲。
WebSocket 的特點:
- 全雙工通訊:WebSocket 連線建立後,客戶端和伺服器都可以主動向對方傳送訊息,而不需要像 HTTP 那樣由客戶端發起請求,伺服器被動響應。這樣可以實現實時性強的應用,如線上聊天、實時更新等。
- 持久化連線:在 WebSocket 連線建立後,連線會一直保持,直到客戶端或伺服器主動關閉連線。這與傳統 HTTP 的短連線模式(請求-響應模式)形成鮮明對比。
- 更少的開銷:在初次連線時,WebSocket 透過 HTTP 協議進行握手,一旦連線建立,通訊就不再使用 HTTP 的頭資訊,從而減少了網路開銷。
- 低延遲:由於連線是持久的,客戶端和伺服器之間的通訊延遲較低,特別適合對延遲敏感的應用場景,比如遊戲、實時監控、股票行情推送等。
WebSocket 的工作流程:
- 建立連線:客戶端發起 WebSocket 連線請求,通常是透過 HTTP 請求。伺服器接收到請求後,如果支援 WebSocket,將進行協議升級,並透過 HTTP 響應建立 WebSocket 連線。
- 資料傳輸:連線建立後,客戶端和伺服器可以透過 WebSocket 傳送資料。WebSocket 的資料傳輸採用幀(frame)方式,支援文字和二進位制資料。
- 關閉連線:任意一方可以隨時主動關閉連線,關閉後,通訊將終止。
WebSocket 的應用場景:
- 即時通訊應用:如線上聊天室、即時訊息應用等,客戶端和伺服器需要實時交換訊息。
- 實時資料推送:如股票行情、新聞推送、體育賽事直播等,伺服器需要將實時資料推送給客戶端。
- 線上遊戲:多人線上遊戲中,客戶端和伺服器之間需要實時同步遊戲狀態和操作。
- 物聯網(IoT):裝置和伺服器之間的實時通訊,感測器資料的實時上傳和處理。
與傳統 HTTP 長輪詢的對比:
- 效率:WebSocket 連線建立後可以一直保持,而 HTTP 長輪詢需要頻繁建立和關閉連線,因此 WebSocket 的通訊效率更高。
- 實時性:WebSocket 是雙向實時通訊,長輪詢則是客戶端定期請求伺服器,存在一定的延遲。
- 開銷:WebSocket 的資料傳輸過程中沒有 HTTP 頭部資訊,而長輪詢每次請求都會帶有 HTTP 頭部,導致開銷較大。
WebSocket 的限制:
- 防火牆和代理:由於 WebSocket 需要保持長連線,某些防火牆和代理可能會阻斷或限制 WebSocket 連線。
- 複雜性:與傳統 HTTP 請求-響應模型相比,WebSocket 的開發和除錯更為複雜。
WebSocket 示例:
客戶端程式碼(JavaScript):
// 建立 WebSocket 連線
const socket = new WebSocket('ws://localhost:8080/ws');
// 連線建立時觸發
socket.onopen = function(event) {
console.log('WebSocket connection established');
socket.send('Hello Server!');
};
// 收到訊息時觸發
socket.onmessage = function(event) {
console.log('Received from server: ' + event.data);
};
// 連線關閉時觸發
socket.onclose = function(event) {
console.log('WebSocket connection closed');
};
// 發生錯誤時觸發
socket.onerror = function(event) {
console.error('WebSocket error: ' + event.message);
};
伺服器程式碼(Spring WebSocket 處理):
public class MyWebSocketHandler extends TextWebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("連線建立: " + session.getId());
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
System.out.println("收到訊息: " + message.getPayload());
session.sendMessage(new TextMessage("Echo: " + message.getPayload()));
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("連線關閉: " + session.getId());
}
}
總結:
WebSocket 提供了一種高效的雙向通訊方式,適用於需要實時互動的應用場景。它的優勢在於低延遲、低開銷和高實時性,但也有一定的複雜性和環境限制。在實際應用中,可以根據具體需求選擇是否使用 WebSock###et。
專案地址
https://gitee.com/lxj_dear/my-web-socket