由於 WebSocket 是長連接,如果一定時間內沒有通訊,連接可能會斷開。這時候需要心跳機制,WebSocket 協議包含了 Ping 和 Pong 兩個幀,可以定時發送 Ping 幀來保持長連接。
1、心跳原理圖:
2、websocket協議控制幀描述
Control frames are identified by opcodes where the most significant bit of the opcode is 1.
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.
Control frames are used to communicate state about the WebSocket.
Control frames can be interjected in the middle of a fragmented message.
All control frames MUST have a payload length of 125 bytes or less and MUST NOT be fragmented.
從原文可知,Ping的協議頭是0x9,Pong的協議頭是0xA,控制幀最大載荷為125bytes且不能拆分
3、代碼示例:
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"; } });
4、關於ping與pong的結論
· 心跳包中可能會攜帶數據
· 當收到Ping幀的時候需要立即返回一個Pong幀
· 在連接建立之后,隨時都可以發送Ping幀
· 心跳是用來測試鏈接是否存在和對方是否在線
· 在響應Ping幀的的Pong幀中,必須攜和被響應的Ping幀中相同的數據
筆者注:目前沒有找到用JS websocket發送ping幀的資料,如果哪位大佬有相關的說明,請不吝賜教。
--------------------------- 我是可愛的分割線 ----------------------------
最后博主借地宣傳一下,漳州編程小組招新了,這是一個面向漳州青少年信息學/軟件設計的學習小組,有意向的同學點擊鏈接,聯系我吧。