成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

WebSocket:心跳檢測與重連機制,你會嗎?

開發 前端
不管是客戶端發送心跳還是服務端發送心跳,連接都有斷開的可能。例如瀏覽器最小化js被暫停、瀏覽器切換到其它tab頁面js被暫停、電腦進入睡眠等等、移動端切換網絡、信號變弱、手機黑屏、手機應用切換到后臺、路由故障、業務主動斷開等。尤其是外網環境復雜,很多路由節點會清理1分鐘內不活躍的連接,這也是為什么心跳間隔推薦小于1分鐘的原因。

為什么需要心跳檢測?

正常的情況客戶端斷開連接會向服務端發送一個fin包,服務端收到fin包后得知客戶端連接斷開,則立刻觸發onClose事件回調。

心跳包格式:WebSocket協議RFC6455中有定義控制幀的格式Ping幀包含一個操作碼0x9,Pong幀包含一個操作碼0xA。客戶端發送Ping幀,服務端收到Ping幀后回一個響應Pong幀。

但是有些極端情況如客戶端掉電、網絡關閉、拔網線、路由故障等,這些極端情況客戶端無法發送fin包給服務端,服務端便無法知道連接已經斷開。如果客戶端與服務端定時有心跳數據傳輸,則會比較及時的發現連接斷開,觸發onClose事件回調。

另外路由節點防火墻會關閉長時間不通訊的socket連接,導致socket長連接斷開。所以需要客戶端與服務端定時發送心跳數據保持連接不被斷開。

心跳原理

客戶端定時每X秒(推薦小于60秒)向服務端發送特定數據(任意數據都可),服務端設定為X秒沒有收到客戶端心跳則認為客戶端掉線,并關閉連接觸發onClose回調。這樣即通過心跳檢測請求維持了連接(避免連接因長時間不活躍而被網關防火墻關閉),也能讓服務端比較及時的知道客戶端是否異常掉線。

心跳包機制

WebSocket心跳包機制WebSocket心跳包是WebSocket協議的保活機制,用于維持長連接。有效的心跳包可以防止長時間不通訊時,WebSocket自動斷開連接。

心跳包是指在一定時間間隔內,WebSocket發送的空數據包。常見的WebSocket心跳包機制如下:

客戶端

客戶端定時向服務器發送心跳數據包,以保持長連接。

this.heartbeatTimer = setInterval(() => {
    ws.send('{"event":"ping","content":"ping heartbeat"}');
}, originData.ping_interval)
服務端

服務器定時向客戶端發送心跳數據包,以檢測客戶端連接是否正常。

$gateway = new Gateway("websocket://0.0.0.0:8783");

$gateway->pingInterval = 55;

$gateway->pingNotResponseLimit = 0;

// 服務端定時向客戶端發送的數據
$gateway->pingData = '{"type":"ping"}';

以上服務端會定時55秒給客戶端發心跳數據{"type":"ping"},而客戶端不需要定時向服務端發送心跳數據。

  • pingNotResponseLimit = 0代表服務端允許客戶端不發送心跳,服務端不會因為客戶端長時間沒發送數據而斷開連接。
  • pingNotResponseLimit = 1,則代表客戶端必須定時發送數據給服務端,否則pingNotResponseLimit*pingInterval=55秒內沒有任何數據發來則關閉對應連接,并觸發onClose。

說明

  • Gateway::$pingInterval心跳檢測時間間隔 單位:秒。如果設置為0代表不做任何心跳檢測。
  • Gateway::$pingNotResponseLimit 客戶端連續$pingNotResponseLimit次$pingInterval時間內不發送任何數據(包括但不限于心跳數據)則斷開鏈接,并觸發onClose。如果設置為0代表客戶端不用發送心跳數據,即通過TCP層面檢測連接的連通性(極端情況至少10分鐘才能檢測到連接斷開,甚至可能永遠檢測不到)
  • Gateway::$pingData 當需要服務端定時給客戶端發送心跳數據時, $gateway->pingData設置為服務端要發送的心跳請求數據,心跳數據是任意的,只要客戶端能識別即可。客戶端收到心跳數據可以忽略不做任何處理。

注意

當設置為服務端主動發送心跳時,心跳間隔并不是100%精準。當客戶端連接成功后,服務端發來的第一個心跳的時間間隔可能要小于服務器設置的值。

當設置為服務端主動發送心跳時,如果客戶端最近有發來數據,那么證明客戶端存活,服務端會省略一個心跳,下個心跳大約1.5*$gateway->pingInterval秒后發送。

如果心跳是客戶端發送,$gateway->pingNotResponseLimit最好大于0,這樣可以及時檢測到一些死連接(連接已經斷開,但是服務端不知道)

心跳機制原理

WebSocket心跳機制的原理是利用心跳包及時發送和接收數據,保證WebSocket長連接不被斷開。

WebSocket心跳機制的原理可以用下面的流程來說明:

  1. 客戶端建立WebSocket連接。
  2. 客戶端向服務器發送心跳數據包,服務器接收并返回一個表示接收到心跳數據包的響應。
  3. 當服務器沒有及時接收到客戶端發送的心跳數據包時,服務器會發送一個關閉連接的請求。
  4. 服務器定時向客戶端發送心跳數據包,客戶端接收并返回一個表示接收到心跳數據包的響應。
  5. 當客戶端沒有及時接收到服務器發送的心跳數據包時,客戶端會重新連接WebSocket

心跳機制作用

  • 保持WebSocket連接不被斷開。
  • 檢測WebSocket連接狀態,及時處理異常情況。
  • 減少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('客戶端定時發送心跳');
    ws.send('{"event":"ping","content":"開源技術小棧我在線呢!"}');
    $timeout = setTimeout(sendHeartbeat, 3000);
}

ws.onclose = function() {
    clearTimeout($timeout);
    console.log('沒有網了,睡覺去了');
};

控制臺檢測記錄

圖片圖片

斷線重連

不管是客戶端發送心跳還是服務端發送心跳,連接都有斷開的可能。例如瀏覽器最小化js被暫停、瀏覽器切換到其它tab頁面js被暫停、電腦進入睡眠等等、移動端切換網絡、信號變弱、手機黑屏、手機應用切換到后臺、路由故障、業務主動斷開等。尤其是外網環境復雜,很多路由節點會清理1分鐘內不活躍的連接,這也是為什么心跳間隔推薦小于1分鐘的原因。

連接在外網環境很容易被斷開,所以斷線重連是長連接應用必須具備的功能(斷線重連只能客戶端做,服務端無法實現)。例如瀏覽器websocket需要監聽onclose事件,當發生onclose時建立新的連接(為避免需崩可延建立連接)。更嚴格一點,服務端也應該定時發起心跳數據,并且客戶端需要定時監測服務端的心跳數據是否超時,超過規定時間未收到服務端心跳數據應該認定連接已經斷開,需要執行close關閉連接,并重新建立新的連接。

責任編輯:武曉燕 來源: 開源技術小棧
相關推薦

2024-03-21 08:34:49

Vue3WebSocketHTTP

2024-12-23 06:00:00

TCPC#網絡

2020-09-30 14:07:05

Kafka心跳機制API

2024-09-06 11:11:20

2021-07-30 15:06:05

鴻蒙HarmonyOS應用

2021-07-20 08:23:49

HTTPWebSocketWeb

2024-05-29 07:50:41

2024-04-29 06:39:45

WebSocketSocketC#

2023-12-04 07:09:53

函數遞歸python

2021-08-19 15:36:09

數據備份存儲備份策略

2024-02-22 08:31:26

數據恢復工具MySQL回滾SQL

2012-06-20 10:47:25

Team Leader

2021-04-14 06:53:52

C# 修飾符 Public

2021-04-16 15:02:11

CAP理論分布式

2019-05-07 15:49:27

AI人工智能藝術

2025-06-03 01:45:00

2010-07-13 10:40:30

唐駿

2020-11-25 09:49:05

Hibernate

2011-09-30 13:37:35

51CTO博客一周熱門薪酬

2022-03-25 09:39:50

LinuxLinux top
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文字幕乱码视频32 | 国内在线视频 | a国产一区二区免费入口 | 久久麻豆精品 | 久久久国产一区 | 国产成人精品久久二区二区91 | 美女在线观看国产 | 四虎影 | 九九久久国产精品 | 日韩欧美在线视频 | 日本激情视频中文字幕 | 国产91丝袜在线熟 | 91精品国产综合久久精品图片 | 亚洲一区在线日韩在线深爱 | 男女视频在线免费观看 | 男人的天堂中文字幕 | 欧美在线网站 | 亚洲精品一区二区二区 | 欧美激情视频一区二区三区在线播放 | 欧美黄色一区 | 色视频在线观看 | 国产精品永久免费 | 国产精品一区二区av | 一级少妇女片 | 亚洲精品一区中文字幕乱码 | 欧美区日韩区 | 国产综合精品一区二区三区 | 91色视频在线 | 精品一区二区三区在线观看 | 中文字幕高清av | 欧美黄色性生活视频 | 精品国产乱码久久久久久老虎 | 超碰在线免费 | 日本亚洲精品成人欧美一区 | 精品日本久久久久久久久久 | 黄色免费在线观看网站 | 天天操天天舔 | 国产精品观看 | 亚洲a在线观看 | av一区在线 | 一本久久a久久精品亚洲 |