因爲 WebSocket 是長鏈接,若是必定時間內沒有通信,鏈接可能會斷開。這時候須要心跳機制,WebSocket 協議包含了 Ping 和 Pong 兩個幀,能夠定時發送 Ping 幀來保持長鏈接。php
一、心跳原理圖:web
二、websocket協議控制幀描述編程
Control frames are identified by opcodes where the most significant bit of the opcode is 1.websocket
Currently defined opcodes for control frames include 0x8 (Close), 0x9 (Ping), and 0xA (Pong). Opcodes 0xB-0xF are reserved for further control frames yet to be defined.less
Control frames are used to communicate state about the WebSocket.socket
Control frames can be interjected in the middle of a fragmented message.ide
All control frames MUST have a payload length of 125 bytes or less and MUST NOT be fragmented.學習
從原文可知,Ping的協議頭是0x9,Pong的協議頭是0xA,控制幀最大載荷爲125bytes且不能拆分測試
三、代碼示例:spa
1) 發送ping幀
use Swoole\WebSocket\Frame; use Swoole\WebSocket\Server; $server = new Server('127.0.0.1', 9501); $server->on('message', function (Server $server, Frame $frame) { $pingFrame = new Frame; $pingFrame->opcode = WEBSOCKET_OPCODE_PING; $server->push($frame->fd, $pingFrame); }); $server->start();
2) 響應ping幀
$server->on('message', function (Swoole\WebSocket\Server $server, $frame) { if ($frame->opcode == 0x09) { echo "Ping frame received: Code {$frame->opcode}\n"; // 回覆 Pong 幀 $pongFrame = new Swoole\WebSocket\Frame; $pongFrame->opcode = WEBSOCKET_OPCODE_PONG; $server->push($frame->fd, $pongFrame); } else { echo "Message received: {$frame->data}\n"; } });
四、關於ping與pong的結論
· 心跳包中可能會攜帶數據
· 當收到Ping幀的時候須要當即返回一個Pong幀
· 在鏈接創建以後,隨時均可以發送Ping幀
· 心跳是用來測試連接是否存在和對方是否在線
· 在響應Ping幀的的Pong幀中,必須攜和被響應的Ping幀中相同的數據
筆者注:目前沒有找到用JS websocket發送ping幀的資料,若是哪位大佬有相關的說明,請不吝賜教。
--------------------------- 我是可愛的分割線 ----------------------------
最後博主借地宣傳一下,漳州編程小組招新了,這是一個面向漳州青少年信息學/軟件設計的學習小組,有意向的同窗點擊連接,聯繫我吧。