乐趣区

关于swoole:Swoole-v47-版本新特性预览之-onDisconnect-事件回调

在之前的版本中可能有这样一种状况,在 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

这样的输入并不能晓得这个 $fd1的连贯是否为 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 3
client-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 3
client-2 is Disconnect

这样就能够间接来辨别连贯是否为 WebSocket 连贯。

WebSocket\Server设置了 onDisconnect 事件回调,非 WebSocket 申请或者在 onRequest 调用 $response->close() 办法,都会回调 onDisconnect。而在 onRequest 事件中失常完结则不会调用onCloseonDisconnect事件。

反之,如果不设置 onDisconnect 事件回调,非 WebSocket 申请或者在 onRequest 调用 $response->close() 办法,则都会调用 onClose 回调。

退出移动版