在之前的版本中可能有这样一种状况,在 WebSocket 服务器中无奈在 close 事件回调中辨别该 fd
是否为 WebSocket 连贯,例如以下代码:
//创立WebSocket Server对象,监听0.0.0.0:9501端口$ws = new Swoole\WebSocket\Server('0.0.0.0', 9501);//监听WebSocket连贯关上事件$ws->on('Open', function ($ws, $request) { $ws->push($request->fd, "hello, welcome\n");});//监听WebSocket音讯事件$ws->on('Message', function ($ws, $frame) { echo "Message: {$frame->data}\n"; $ws->push($frame->fd, "server: {$frame->data}");});//监听WebSocket连贯敞开事件$ws->on('Close', function ($ws, $fd) { echo "client-{$fd} is closed\n";});$ws->start();
启动服务后,应用浏览器对127.0.0.1:9501
发动申请,终端会失去输入:
client-1 is closed[2021-05-24 16:58:08 *37715.1] NOTICE end (ERRNO 1005): session[1] is closed
这样的输入并不能晓得这个$fd
为1
的连贯是否为 WebSocket 连贯。如果业务代码中存在间接应用该$fd
去做一些逻辑解决是无用的,也有可能会产生有人歹意申请导致占用资源。
那么相熟 Swoole 开发的人就会想到能够减少判断:应用 getClientInfo 办法的websocket_status
值来获取 WebSocket 连贯状态
当服务器是 WebSocket\Server
时, getClientInfo
会额定减少websocket_status
信息,它有对应的 4 种状态,别离为
常量 | 对应值 | 阐明 |
---|---|---|
WEBSOCKET_STATUS_CONNECTION | 1 | 连贯进入期待握手 |
WEBSOCKET_STATUS_HANDSHAKE | 2 | 正在握手 |
WEBSOCKET_STATUS_ACTIVE | 3 | 已握手胜利期待浏览器发送数据帧 |
WEBSOCKET_STATUS_CLOSING | 4 | 连贯正在进行敞开握手,行将敞开 |
能够批改上述代码中的 onClose
回调:
$ws->on('Close', function ($ws, $fd) { $is_websocket = $ws->getClientInfo($fd)['websocket_status']; if ($is_websocket) { echo "client-{$fd} is closed, WebSocket status is {$is_websocket}\n"; } else { echo "client-{$fd} is not a valid WebSocket connection\n"; }});
WebSocket\Server
还能够设置onRequest
回调,同理减少:
$ws->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) { if (isset($request->get['close'])) { $response->close(); }});
重启服务器,别离应用 WebSocket 客户端来申请后敞开和浏览器申请 http://127.0.0.1:9501/?close=1
后会失去这样的输入:
client-1 is closed, WebSocket status is 3client-2 is not a valid WebSocket connection
当初从 v4.7.0
版本开始,减少了 onDisconnect
事件回调,在上述代码中减少:
//监听WebSocket谬误的连贯敞开事件$ws->on('Disconnect', function ($ws, $fd) { echo "client-{$fd} is Disconnect\n";});
重启服务器,发动申请会失去:
client-1 is closed, WebSocket status is 3client-2 is Disconnect
这样就能够间接来辨别连贯是否为 WebSocket 连贯。
WebSocket\Server
设置了 onDisconnect
事件回调,非 WebSocket 申请或者在 onRequest
调用 $response->close()
办法,都会回调onDisconnect
。而在 onRequest
事件中失常完结则不会调用onClose
或onDisconnect
事件。
反之,如果不设置 onDisconnect
事件回调,非 WebSocket 申请或者在 onRequest
调用 $response->close()
办法,则都会调用onClose
回调。