iT邦幫忙

2

聊天軟體實作(3): 訊息怎麼推送-心跳包

  • 分享至 

  • xImage
  •  

話說 html5 之後,Web 端要及時通訊多了 SSE(Server-Sent-Event) 和 WebSocket。

SSE簡單來說就是長輪詢(Long-polling)的進階版,透過javaScript API處理,只能由Server單向發送給Client。

Websocket 提供全雙工、雙向的資料傳輸,這點相當適合用在線上聊天室或遊戲。

不過即時性要求不高時,又想在瀏覽器間兼容,長輪詢(Long-polling)這種方式,還是一種選擇。

網路上的比較文章很多,這裡不贅述,想談談一個實作 Websocket 的眉角。

心跳包(HeartBeat)的重要性

https://ithelp.ithome.com.tw/upload/images/20220802/20139626BifAUlL7ph.png

在第一次握手(Handshake)後,便會建立一個長連線。而網路斷線等意外,並不會呼叫 Server端的 OnClose(),導致 Server 端一廂情願推送、苦苦等候。

透過定時/不定時確認連線狀態,除了能清除占用的連線資源,也能及時處理聊天室使用者斷線,比如 Client 端的斷線重連,增進服務體驗。

RFC 6455中定義了幾種 WebSocket 資料傳輸單位(frame):text data、binary data、ping/pong、close等。

其中,兩端都可以透過 ping/pong 來做心跳檢測。

A Ping frame may serve either as a keepalive or as a means to verify that the remote endpoint is still responsive.

當Client收到一個 Ping,必須回傳 Pong,告訴 Server: 他還活著。反之亦然。

Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in response, unless it already received a Close frame. It SHOULD respond with a Pong frame as soon as is practical.

注意:
WebSocket 是基於 TCP 協議,
TCP 的 keep-alive 機制(同樣是確認狀態),
無法確認當前應用層的 Application 連線可不可用
WebSockets ping/pong, why not TCP keepalive? - Stack Overflow

在實踐上,假設兩端有頻繁的數據互動,那透過定時的心跳檢測,便會浪費傳輸流量。通常會記錄上一次接收/發送 Websocket 訊息的時間,假設超過預設時間,才發送心跳包。

簡單的做法如下:

https://ithelp.ithome.com.tw/upload/images/20220802/201396269yxN47XUBA.png

上一篇: 聊天軟體實作(2):從讀寫需求評估資料儲存


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Terry L.
iT邦研究生 3 級 ‧ 2022-08-09 10:42:35

寫的很好,其實你可以留在鐵人賽再發文的說? 說不定可以拿到獎項

wowlol iT邦新手 5 級 ‧ 2022-08-10 09:30:54 檢舉

謝謝你的鼓勵!目前就是單純紀錄跟分享,希望自己在實做跟概念上都有所進步~

我要留言

立即登入留言