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

沈唁
+关注
目录
打赏
0
0
0
0
1
分享
相关文章
Linux进程信号【信号处理】
Linux进程信号【信号处理】
225 0
如何让Vue项目本地运行的时候,同时支持http://localhost和http://192.168.X.X访问?
如何让Vue项目本地运行的时候,同时支持http://localhost和http://192.168.X.X访问?
未来家居生活的智能化革命:探索物联网技术在智能家居中的应用
【8月更文挑战第5天】当物联网技术遇上智能家居,一场关于便捷、舒适与节能的生活革命悄然拉开帷幕。本文将探讨物联网如何通过高度互联的设备网络,实现家庭环境的智能管理,提升居住体验的同时,促进能源的有效利用。
MySQL和PostgreSQL的常用语法差异
背景 在去年的DBMS评比中,PostgreSQL夺冠,PostgreSQL一直保持上升姿态,越来越多的客户选择使用PostgreSQL,还有一部分客户从MySQL迁往PostgreSQL,那PostgreSQL和MySQL对于开发者来说的差异在哪里呢?末学对比了下语法差异,不一样的地方用红色标记了出来,供大家参考。
13553 0
thinkphp SQLSTATE[08001]: [Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: [error:14090086:SSL routine
thinkphp SQLSTATE[08001]: [Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: [error:14090086:SSL routine
1298 0
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
【最新版正确姿势】Docker安装教程(简单几步即可完成)
之前的老版本Docker安装教程已经发生了变化,本文分享了Docker最新版安装教程,其他操作系统版本也可以参考官 方的其他安装版本文档。
8845 3
【最新版正确姿势】Docker安装教程(简单几步即可完成)
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问