WebsocketClient连接一段时间后不知原因onClose,而且reConnect失败

zhyt0520

WebsocketClient开始可以正常连接,每三十秒发送数据,可正常接收返回数据。过几小时到十几小时不等,之后会onClose(不知道啥原因),我在里面运行reConnect,有时可以重连成功,有时失败。
从没有触发过onError。
报错:Sec-WebSocket-Accpet not match.
图片
而且一大串数据输出之后还有error package. package_length=false
 
在网上搜了半天没找到相关内容,还请大佬指点

服务端用的GatewayWorker
下面是客户端的启动文件

use Workerman\Worker;
use Workerman\Connection\AsyncTcpConnection;
use \Workerman\Lib\Timer;

require_once __DIR__ . '/Workerman/Autoloader.php';

date_default_timezone_set("PRC");

$worker = new Worker();

$worker->onWorkerStart = function($worker){

    $reConnentTimer = null;
    $file = null;

    $conn = new AsyncTcpConnection('ws://39.105.170.46:8282');

    $conn->onConnect = function($conn) {
        $conn->send('send onConnect');
        Timer::add(30, function() use ($conn)
        {
            $conn->send(date("Y-m-d H:i:s"));
        });
        echo "run Timer::add( send message )\n";
        global $file;
        if (!isset($file)) {
            $file = fopen('stdout.log','a');
        }
        fwrite($file, "run Timer::add( send message )"."\n");
    };

    $conn->onMessage = function($conn, $data) {
        echo $data;
        global $file;
        if (!isset($file)) {
            $file = fopen('stdout.log','a');
        }
        fwrite($file, $data);
        global $reConnentTimer;
        if ($reConnentTimer) {
            Timer::del($reConnentTimer);
            $reConnentTimer = null;
            echo "run Timer::del( reConnect )\n";
            global $file;
            if (!isset($file)) {
                $file = fopen('stdout.log','a');
            }
            fwrite($file, "run Timer::del( reConnect )"."\n");
        }
    };

    $conn->onClose = function($conn) {
        echo "run onClose()";
        global $reConnentTimer;
        global $file;
        if ($reConnentTimer == null) {
            $reConnentTimer = Timer::add(3, function() use ($conn,$file)
            {
                $conn->reConnect(0);
                echo "run reConnect()\n";
                if (!isset($file)) {
                    $file = fopen('stdout.log','a');
                }
                fwrite($file, "run reConnect()"."\n");
            });
            echo "run Timer::add( reConnect )\n";
            global $file;
            if (!isset($file)) {
                $file = fopen('stdout.log','a');
            }
            fwrite($file, "run Timer::add( reConnect )"."\n");
        }
    };

    $conn->onError = function($conn, $code, $msg) {
        echo "error $code $msg\n";
        global $file;
        if (!isset($file)) {
            $file = fopen('stdout.log','a');
        }
        fwrite($file, "error $code $msg"."\n");
    };

    $conn->connect();
};

Worker::runAll();
10101 3 0
3个回答

blogdaren
  1. 保证已经成功设置好了心跳。
  2. 客户端onClose方法中关于Timer部分的代码整体替换为:$conn->onClose = function($conn) {
    $conn->reconnect(3);
    }
  • zhyt0520 2019-02-07

    心跳这么用的,应该可以吧,每三十秒发送一次
    $conn->onConnect = function($conn) {
    Timer::add(30, function() use ($conn)
    {
    $conn->send(date("Y-m-d H:i:s"));
    });

    onClose回调中的reConnect,我之前就是你说的这样写的,运行时间长了出问题,终端的输出会停在最后一个reConnect(),看不到其他任何信息,之后我才改成现在的样子,看到了Sec-WebSocket-Accpet not match.看到了截图里的信息

  • walkor 2019-02-08

    更新下workerman试下

  • zhyt0520 2019-02-12

    @1:查了一下,服务端的worker是3.5.17,客户端这边是3.5.18,跟版本不一致有关系吗?把服务端更新成3.5.18?

  • walkor 2019-02-12

    对,更新下就好了

  • zhyt0520 2019-02-13

    @1:

zhyt0520

@walkor: 
我更新完workerman,不再报错了Sec-WebSocket-Accpet not match.但是重连连不上的问题仍然没解决,客户端这边是下面截图的样子,服务端那边也没有错误信息
[attach]1716[/attach] 
多次测试发现,发生 onClose 并且 reConnect 连不上的情况都出现在早晨六点五十多的时候
而且这个客户端连不上的时候,我再开个新的客户端去连服务器也连不上,把出问题这个关掉之后,就可以再开多个客户端重新连接服务器了
 
还麻烦大佬给看看问题在哪,或者指点我一下监控进程的思路,发现reConnect失败之后如何关掉当前进程并重新开一个新的

  • walkor 2019-02-13

    按照手册优化下linux内核,安装下event扩展

  • zhyt0520 2019-02-13

    @1:我测试的时候是只连了一个客户端的,我看手册上写是并发高的时候需要优化内核

walkor

 $conn->onClose = function($conn) {
$conn->reconnect(3);
};
重连是这样重连的,自身已经有定时逻辑,不能再放到定时器里。

  • zhyt0520 2019-02-15

    升级3.5.18,并且把重连改回
    $conn->onClose = function($conn) {
    $conn->reconnect(3);
    };
    这样用一个客户端连了快三天了,还是每天早晨六点五十多会断开,但是可以成功重连

  • zhyt0520 2019-02-15

    每天早晨六点五十多断这一下,是workerman里的设置吗?还是我这服务器或者客户端的问题?

  • walkor 2019-02-16

    workerman没这个设置。有可能服务端会定时关闭连接

  • zhyt0520 2019-02-17

    @1:运行了四天多,今天早晨断了没重连上。workerman里reConnect()失败之后默认是什么处理逻辑啊?可以自定义吗?

  • walkor 2019-02-18

    reconnect失败后会执行onClose,由于reconnect还会在onClose里调用,所以还会再次重连

年代过于久远,无法发表回答
🔝