gateway使用心跳报文,服务端ws链接仍然会断开链接

yifenbushe

问题描述

使用gateway做长连接,未做心跳时,1分钟不发送消息就断开链接,增加心跳报文后,分钟左右也会断开链接,不清楚什么原因。

程序代码

终端心跳报文计时如下,每次收到、发送消息都会重新计时,终端ws.closed已经注释掉:
let timer;

// 定时器函数
function startTimer() {
    clearInterval(timer); // 确保只有一个定时器在运行

    // 发送ping报文的逻辑
    function sendPing() {
        ws.send('ping');
        console.log("发送ping报文");
        // 重置计数器的逻辑
        resetTimer();
    }

    // 启动定时器
    timer = setInterval(sendPing, 50000); // 每50秒执行一次sendPing函数
}

// 重置计数器函数
function resetTimer() {
    clearInterval(timer);
    startTimer();
}

// 启动定时器
startTimer();

服务端把start_gateway.php中注释代码去掉,简单做了修改如下:

// 心跳间隔
$gateway->pingInterval = 55;
// 心跳数据
$gateway->pingData = 'ping';

报错信息

WebSocket is already in CLOSING or CLOSED state.

截图报错信息里报错文件相关代码

截图

操作系统及workerman/webman等框架组件具体版本

操作系统ubuntu;
Workerman version:4.1.11
PHP version:8.1.2-1ubuntu2.13

571 1 0
1个回答

latin

"每次收到、发送消息都会重新计时" 这个感觉会出现bug。如果服务端强制要求每55秒发一个心跳包,但是你延迟了下比如60秒才发送,那么连接可能就被服务端断开了。

  • yifenbushe 2023-08-13

    但是发消息之后5分钟一直都可以正常通信,断开是在定时发送ping的过程

  • yifenbushe 2023-08-14

    而且刷新界面,重新建立链接,一个消息也不发的情况下,还是会自动断开,只是断开时间不一样,有一个浏览器窗口400s断开了,有一个500s+了还没断开,奇怪,感觉不稳定,环境在虚拟机中,理论上不会是网络的问题

  • yifenbushe 2023-08-14

    自己顶下帖子吧,有可能是浏览器原因,firefox就不会断开,但是,chrome就会断开,网上查询可能对websocket处理机制不一样,chrome发生心跳报文后,还需要接收到心跳报文才行,不然认为已断开,求证!!

  • 小W 2023-08-14

    之前我也遇到过chrome浏览器没有任何操作一段时间就会自动断开,使用ws测试工具试一下

  • latin 2023-08-14

    那就gatewayWorker收到心跳返回一个数据试下呗

  • yifenbushe 2023-08-14

    chrome 使用在线测试工具,在发送不固定的几个ping包之后,就出现10:34:19 => CLOSED => 1006 CLOSE_ABNORMAL,firefox 不会,一直处于正常情况。
    网上解释:
    当Chrome浏览器不符合WebSocket标准时,情况就是这样。当服务器启动关闭并向客户端发送关闭帧时,Chrome认为这是错误,并使用代码1006并没有原因消息将其报告给JS端。在我的测试中,Chrome从未响应服务器启动的关闭帧(关闭代码1000),表明代码1006可能表示Chrome正在报告自己的内部错误。

    PS Firefox v57.00可以正确处理此情况,并成功将服务器的原因消息传递给JS端。

  • yifenbushe 2023-08-14

    已解决:
    业务端处理心跳报文,并返回一个包,问题解决。

🔝