新聞中心
為什么需要心跳檢測?
正常的情況客戶端斷開連接會向服務端發(fā)送一個fin包,服務端收到fin包后得知客戶端連接斷開,則立刻觸發(fā)onClose事件回調。

十多年的鷹手營子網站建設經驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。成都全網營銷的優(yōu)勢是能夠根據(jù)用戶設備顯示端的尺寸不同,自動調整鷹手營子建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現(xiàn)優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“鷹手營子網站設計”,“鷹手營子網站推廣”以來,每個客戶項目都認真落實執(zhí)行。
心跳包格式:WebSocket協(xié)議RFC6455中有定義控制幀的格式Ping幀包含一個操作碼0x9,Pong幀包含一個操作碼0xA。客戶端發(fā)送Ping幀,服務端收到Ping幀后回一個響應Pong幀。
但是有些極端情況如客戶端掉電、網絡關閉、拔網線、路由故障等,這些極端情況客戶端無法發(fā)送fin包給服務端,服務端便無法知道連接已經斷開。如果客戶端與服務端定時有心跳數(shù)據(jù)傳輸,則會比較及時的發(fā)現(xiàn)連接斷開,觸發(fā)onClose事件回調。
另外路由節(jié)點防火墻會關閉長時間不通訊的socket連接,導致socket長連接斷開。所以需要客戶端與服務端定時發(fā)送心跳數(shù)據(jù)保持連接不被斷開。
心跳原理
客戶端定時每X秒(推薦小于60秒)向服務端發(fā)送特定數(shù)據(jù)(任意數(shù)據(jù)都可),服務端設定為X秒沒有收到客戶端心跳則認為客戶端掉線,并關閉連接觸發(fā)onClose回調。這樣即通過心跳檢測請求維持了連接(避免連接因長時間不活躍而被網關防火墻關閉),也能讓服務端比較及時的知道客戶端是否異常掉線。
心跳包機制
WebSocket心跳包機制WebSocket心跳包是WebSocket協(xié)議的?;顧C制,用于維持長連接。有效的心跳包可以防止長時間不通訊時,WebSocket自動斷開連接。
心跳包是指在一定時間間隔內,WebSocket發(fā)送的空數(shù)據(jù)包。常見的WebSocket心跳包機制如下:
客戶端
客戶端定時向服務器發(fā)送心跳數(shù)據(jù)包,以保持長連接。
this.heartbeatTimer = setInterval(() => {
ws.send('{"event":"ping","content":"ping heartbeat"}');
}, originData.ping_interval)
服務端
服務器定時向客戶端發(fā)送心跳數(shù)據(jù)包,以檢測客戶端連接是否正常。
$gateway = new Gateway("websocket://0.0.0.0:8783");
$gateway->pingInterval = 55;
$gateway->pingNotResponseLimit = 0;
// 服務端定時向客戶端發(fā)送的數(shù)據(jù)
$gateway->pingData = '{"type":"ping"}';以上服務端會定時55秒給客戶端發(fā)心跳數(shù)據(jù){"type":"ping"},而客戶端不需要定時向服務端發(fā)送心跳數(shù)據(jù)。
- pingNotResponseLimit = 0代表服務端允許客戶端不發(fā)送心跳,服務端不會因為客戶端長時間沒發(fā)送數(shù)據(jù)而斷開連接。
- pingNotResponseLimit = 1,則代表客戶端必須定時發(fā)送數(shù)據(jù)給服務端,否則pingNotResponseLimit*pingInterval=55秒內沒有任何數(shù)據(jù)發(fā)來則關閉對應連接,并觸發(fā)onClose。
說明
- Gateway::$pingInterval心跳檢測時間間隔 單位:秒。如果設置為0代表不做任何心跳檢測。
- Gateway::$pingNotResponseLimit 客戶端連續(xù)$pingNotResponseLimit次$pingInterval時間內不發(fā)送任何數(shù)據(jù)(包括但不限于心跳數(shù)據(jù))則斷開鏈接,并觸發(fā)onClose。如果設置為0代表客戶端不用發(fā)送心跳數(shù)據(jù),即通過TCP層面檢測連接的連通性(極端情況至少10分鐘才能檢測到連接斷開,甚至可能永遠檢測不到)
- Gateway::$pingData 當需要服務端定時給客戶端發(fā)送心跳數(shù)據(jù)時, $gateway->pingData設置為服務端要發(fā)送的心跳請求數(shù)據(jù),心跳數(shù)據(jù)是任意的,只要客戶端能識別即可。客戶端收到心跳數(shù)據(jù)可以忽略不做任何處理。
注意
當設置為服務端主動發(fā)送心跳時,心跳間隔并不是100%精準。當客戶端連接成功后,服務端發(fā)來的第一個心跳的時間間隔可能要小于服務器設置的值。
當設置為服務端主動發(fā)送心跳時,如果客戶端最近有發(fā)來數(shù)據(jù),那么證明客戶端存活,服務端會省略一個心跳,下個心跳大約1.5*$gateway->pingInterval秒后發(fā)送。
如果心跳是客戶端發(fā)送,$gateway->pingNotResponseLimit最好大于0,這樣可以及時檢測到一些死連接(連接已經斷開,但是服務端不知道)
心跳機制原理
WebSocket心跳機制的原理是利用心跳包及時發(fā)送和接收數(shù)據(jù),保證WebSocket長連接不被斷開。
WebSocket心跳機制的原理可以用下面的流程來說明:
- 客戶端建立WebSocket連接。
- 客戶端向服務器發(fā)送心跳數(shù)據(jù)包,服務器接收并返回一個表示接收到心跳數(shù)據(jù)包的響應。
- 當服務器沒有及時接收到客戶端發(fā)送的心跳數(shù)據(jù)包時,服務器會發(fā)送一個關閉連接的請求。
- 服務器定時向客戶端發(fā)送心跳數(shù)據(jù)包,客戶端接收并返回一個表示接收到心跳數(shù)據(jù)包的響應。
- 當客戶端沒有及時接收到服務器發(fā)送的心跳數(shù)據(jù)包時,客戶端會重新連接WebSocket
心跳機制作用
- 保持WebSocket連接不被斷開。
- 檢測WebSocket連接狀態(tài),及時處理異常情況。
- 減少WebSocket連接及服務器資源的消耗。
完整代碼
服務端心跳(不推薦)
修改配置文件config\plugin\webman\gateway-worker\process.php進程配置文件。
'pingInterval' => 30,
'pingNotResponseLimit' => 0,
'pingData' => '{"event":"ping","msg":"我是服務端主動心跳檢測"}',
控制臺檢測記錄
圖片
客戶端心跳(推薦)
let $timeout = null;
let ws = new WebSocket("ws://127.0.0.1:8783");
ws.onopen = function(evt) {
let $_content = {
"event": "join",
"mode": 1,
"group_id": 0,
"from_user_id": "10086",
"from_username": "開源技術小棧",
"to_user_id": "10000",
"content": "加入會話",
};
ws.send(JSON.stringify($_content));
};
ws.onmessage = function(evt) {
console.log( "【開源技術小?!拷邮芟? " + evt.data);
let _obj = JSON.parse(evt.data);
if (_obj.data.event === 'init') {
sendHeartbeat();
}
};
function sendHeartbeat() {
console.log('客戶端定時發(fā)送心跳');
ws.send('{"event":"ping","content":"開源技術小棧我在線呢!"}');
$timeout = setTimeout(sendHeartbeat, 3000);
}
ws.onclose = function() {
clearTimeout($timeout);
console.log('沒有網了,睡覺去了');
};
控制臺檢測記錄
圖片
斷線重連
不管是客戶端發(fā)送心跳還是服務端發(fā)送心跳,連接都有斷開的可能。例如瀏覽器最小化js被暫停、瀏覽器切換到其它tab頁面js被暫停、電腦進入睡眠等等、移動端切換網絡、信號變弱、手機黑屏、手機應用切換到后臺、路由故障、業(yè)務主動斷開等。尤其是外網環(huán)境復雜,很多路由節(jié)點會清理1分鐘內不活躍的連接,這也是為什么心跳間隔推薦小于1分鐘的原因。
連接在外網環(huán)境很容易被斷開,所以斷線重連是長連接應用必須具備的功能(斷線重連只能客戶端做,服務端無法實現(xiàn))。例如瀏覽器websocket需要監(jiān)聽onclose事件,當發(fā)生onclose時建立新的連接(為避免需崩可延建立連接)。更嚴格一點,服務端也應該定時發(fā)起心跳數(shù)據(jù),并且客戶端需要定時監(jiān)測服務端的心跳數(shù)據(jù)是否超時,超過規(guī)定時間未收到服務端心跳數(shù)據(jù)應該認定連接已經斷開,需要執(zhí)行close關閉連接,并重新建立新的連接。
網站標題:WebSocket:心跳檢測與重連機制,你會嗎?
本文鏈接:http://www.5511xx.com/article/dphodhj.html


咨詢
建站咨詢
