Swoole v4.7 版本新特性预览之 onDisconnect 事件回调

简介: 在之前的版本中可能有这样一种情况,在 WebSocket 服务器中无法在 close 事件回调中区分该 fd 是否为 WebSocket 连接

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

目录
相关文章
|
测试技术 API Windows
使用钩子(Hook)实现Revit API中 PickObjects 完成按钮的触发
使用钩子(Hook)实现Revit API中 PickObjects 完成按钮的触发
使用钩子(Hook)实现Revit API中 PickObjects 完成按钮的触发
|
1月前
Nest.js 实战 (十二):优雅地使用事件发布/订阅模块 Event Emitter
这篇文章介绍了在Nest.js构建应用时,如何通过事件/发布-订阅模式使应用程序更健壮、灵活、易于扩展,并简化服务间通信。文章主要围绕@nestjs/event-emitter模块展开,这是一个基于eventemitter2库的社区模块,提供了事件发布/订阅功能,使得实现事件驱动架构变得简单。文章还介绍了如何使用该模块,包括安装依赖、初始化模块、注册EventEmitterModule、使用装饰器简化监听等。最后总结,集成@nestjs/event-emitter模块可以提升应用程序的事件驱动能力,构建出更为松耦合、易扩展且高度灵活的系统架构,是构建现代、响应迅速且具有高度解耦特性的Nest.
|
3月前
|
存储 API Android开发
kotlin开发安卓app,使用webivew 触发 onShowFileChooser, 但只能触发一次,第二次无法触发,是怎么回事。 如何解决
在Android WebView开发中,`onShowFileChooser`方法用于开启文件选择。当用户只能选择一次文件可能是因为未正确处理选择回调。解决此问题需确保:1) 实现`WebChromeClient`并覆写`onShowFileChooser`;2) 用户选择文件后调用`ValueCallback.onReceiveValue`传递URI;3) 传递结果后将`ValueCallback`设为`null`以允许再次选择。下面是一个Kotlin示例,展示如何处理文件选择和结果回调。别忘了在Android 6.0+动态请求存储权限,以及在Android 10+处理分区存储。
|
5月前
|
小程序
Uniapp 解决组件在官方文档不支持的事件上,接收小程序原生组件事件
Uniapp 解决组件在官方文档不支持的事件上,接收小程序原生组件事件
89 0
|
数据库连接
Yii2.0框架中如何进行事件处理?它支持哪些事件?
Yii2.0框架中如何进行事件处理?它支持哪些事件?
197 0
|
测试技术 PHP
Laravel 8 新特性: 动态Blade组件、事件监听器优化、事件测试助手
Laravel 8 通过引入 Laravel Jetstream,模型工厂类,迁移压缩,队列批处理,改善速率限制,队列改进,动态 Blade 组件,Tailwind 分页视图, 时间测试助手,artisan serve 的改进,事件监听器的改进,以及各种其他错误修复和可用性改进,对 Laravel 7.x 继续进行了改善。
313 0
|
JavaScript 数据库连接 Linux
Swoole v5.0 版本新特性预览之新的运行模式
PHP 8.1 版本已经在 2021年 11 月 25 日发布了,Swoole 也在第一时间进行了兼容处理,但由于强类型的一些限制,都会导致一些BC的情况发生。 于是目前将master分支不再作为 4.9版本发布,而调整为 5.0版本发布,预计发布时间为农历新年后。
508 1
|
数据可视化
autojs全局事件监听
autojs全局事件监听
626 0
|
API 调度 PHP
Swoole v4.7 版本新特性预览之 Co::cancel()
相信之前就有很多用户想要一个取消协程的 API,迟迟没有添加进来,现在在 v4.7 版本中进行了添加: 具体实现见:#4247 ,#4249
181 0
|
域名解析 网络协议 NoSQL
Swoole v4.7 版本预览之支持 c-ares
c-ares 是一个异步 DNS 解析库。 它适用于需要在不阻塞的情况下执行 DNS 查询或需要并行执行多个 DNS 查询的应用程序。
549 0