In the previous version, there may be such a situation, in the close event callback in the WebSocket server, it is impossible to distinguish whether the fd
is a WebSocket connection, for example, the following code:
//创建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();
After starting the service, use the browser to 127.0.0.1:9501
, and the terminal will get the output:
client-1 is closed
[2021-05-24 16:58:08 *37715.1] NOTICE end (ERRNO 1005): session[1] is closed
Such output does not know $fd
to 1
is a WebSocket connection. It is useless to directly use the $fd
do some logical processing in the business code, and it may also happen that someone maliciously requests to occupy resources.
So familiar Swoole development of people will think of can be added to determine: Use getClientInfo method websocket_status
value to get the WebSocket connection status
When the server is WebSocket\Server
, getClientInfo
will add additional websocket_status
information, which has 4 corresponding states, namely
constant | Corresponding value | Description |
---|---|---|
WEBSOCKET_STATUS_CONNECTION | 1 | Connection enters waiting for handshake |
WEBSOCKET_STATUS_HANDSHAKE | 2 | Shaking hands |
WEBSOCKET_STATUS_ACTIVE | 3 | The handshake has been successful, waiting for the browser to send the data frame |
WEBSOCKET_STATUS_CLOSING | 4 | The connection is in the process of closing handshake and will be closed soon |
You can modify the onClose
callback in the above code:
$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
can also set the onRequest
callback, the same increase:
$ws->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) {
if (isset($request->get['close'])) {
$response->close();
}
});
Restart the server, use the WebSocket client to request and close the request and the browser to request http://127.0.0.1:9501/?close=1
, and you will get this output:
client-1 is closed, WebSocket status is 3
client-2 is not a valid WebSocket connection
Now starting from the v4.7.0
version, the onDisconnect
event callback has been added, and the following code has been added:
//监听WebSocket错误的连接关闭事件
$ws->on('Disconnect', function ($ws, $fd) {
echo "client-{$fd} is Disconnect\n";
});
Restart the server, you will get:
client-1 is closed, WebSocket status is 3
client-2 is Disconnect
In this way, you can directly distinguish whether the connection is a WebSocket connection.
WebSocket\Server
sets the onDisconnect
event callback, non-WebSocket requests or calling the $response->close()
onRequest
will call back onDisconnect
. However, if the onRequest
event ends normally, the onClose
or onDisconnect
event will not be called.
Conversely, if you do not set the onDisconnect
event callback, non-WebSocket request or call the $response->close()
onRequest
onClose
callback will be called.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。