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回调。

目录
相关文章
|
8月前
|
传感器 Android开发 iOS开发
Flutter插件开发指南02: 事件订阅 EventChannel
上一节我们讲了 Channel 通道,但是如果你是卫星定位业务,原生端主动推消息给 Flutter 这时候就要用到 EventChannel 通道了。 本节会写一个 1~50 的计数器,到 50 后自动关闭原生的消息订阅。
160 1
Flutter插件开发指南02:  事件订阅 EventChannel
|
安全 API 网络安全
Swoole v4.6.0 版本发布,支持原生 curl 协程客户端
Swoole v4.6.0 版本发布了,同样也是 2021 年的首个版本更新。 作为一个 y 版本发布,此次更新也包含了不兼容的修改以及许多的新功能
752 0
|
2月前
|
监控 开发者 UED
鸿蒙5.0版开发:订阅卡死事件(ArkTS)
在HarmonyOS 5.0中,开发者可以通过ArkTS订阅应用的卡死事件,以便在应用卡死时进行处理。本文详细介绍如何在ArkTS中订阅卡死事件,并提供示例代码。通过导入hiAppEvent和hilog模块,设置自定义参数,添加事件观察者,开发者可以监控应用稳定性并在问题发生时快速定位原因。示例代码展示了如何创建按钮订阅卡死事件,并在事件发生时通过回调函数处理和记录日志。
57 5
|
2月前
|
存储 UED 开发者
Flutter鸿蒙版本灵活使用方法间的回调处理复杂化的逻辑
在 Flutter 开发中,灵活使用函数回调可以提高代码的可重用性、简化异步编程、增强解耦设计和提升用户体验。本文通过一个简单的示例,展示了如何在 Flutter 中实现函数调用和回调的基本使用。示例代码包括主入口、页面组件和回调函数的定义与调用,详细解析了每个部分的功能和作用。通过这种方式,开发者可以在操作完成后执行特定逻辑,使代码更易读和维护。
97 0
|
5月前
|
存储 开发者 UED
Flutter笔记:谈Material状态属性-为什么FlatButton等旧版按钮就废弃了
Flutter笔记:谈Material状态属性-为什么FlatButton等旧版按钮就废弃了
111 4
|
7月前
|
Web App开发
updog的一个bug修复 支持多线程 视频播放支持跳转
Updog是款实用的局域网多媒体服务器,适合在家观看电视剧。与UC浏览器配合,提供流畅体验。然而,目前存在两个问题:仅允许单用户访问和视频无法跳转。作者已fork原项目,修复这两个bug,并提交了PR([https://github.com/sc0tfree/updog/pull/47r](https://github.com/sc0tfree/updog/pull/47r))。如需立即解决,可直接修改`site-packages/updog/__main__.py`。
|
8月前
|
小程序
Uniapp 解决组件在官方文档不支持的事件上,接收小程序原生组件事件
Uniapp 解决组件在官方文档不支持的事件上,接收小程序原生组件事件
120 0
|
数据库连接
Yii2.0框架中如何进行事件处理?它支持哪些事件?
Yii2.0框架中如何进行事件处理?它支持哪些事件?
214 0
|
Web App开发 前端开发 JavaScript
React Native 0.64版本发布,iOS开启支持Hermes引擎
React Native 0.64版本发布,iOS开启支持Hermes引擎
557 0

热门文章

最新文章