作为客户端使用,close后之前的ping还在?

vasileon

我通过如下代码断开连接

  var_dump($connection->lastTime);
                            //lastTime在收到正常数据时会设置成当前时间,用于判断是否超时没收到信息
                            if ($connection->lastTime < time() - 60 * 5) {
                                var_dump('超时关闭链接 '.$account['id']);
                                unset($connections[$account['id']]);  //$connections 维护了多个用户的链接
                                $connection->close();
                            }

但是断开后发现原来的ping还在,服务端 还会回pong

   Timer::add(15, function () use ($connection) {
                            $connection->send('{"op": "ping"}');
                        });
1200 1 0
1个回答

vasileon

以下是完整代码

global $worker;
        $worker = new Worker();
        $worker->name = 'ws_1';
        $worker->count = 1;

        // 进程启动时
        $worker->onWorkerStart = function ($worker) {
            $pR = Predis::getInstance()->client;

            Timer::add(1, function () use ($pR) {
                // 用来存储哪些用户已经建立连接
                static $connections = [];

                $aKey = 'ws_account_list';
                $accounts = $pR->get($aKey);
                $accounts = json_decode($accounts, true);

                if (!$accounts) {
                    return;
                }

                foreach ($accounts as $account) {
                    $accountId = $account['id'];
                    // 判断这个用户是否建立连接
                    if (isset($connections[$accountId])) {
                        continue;
                    }
                    $ws_connection
                        = new AsyncTcpConnection("ws://xxx.com/ws/");
                    $ws_connection->transport = "ssl";

                    $connections[$accountId] = $ws_connection;
                    $ws_connection->onConnect = function ($connection) use (
                        $account,
                        &$connections
                    ) {
                        var_dump("链接上了".$account['id']);
                        $connection->lastTime = time();
                        $time = time() * 1000;
                        $api_secret = $account['api_secret'];
                        $sig = bin2hex(hash_hmac("sha256",
                            $time."websocket_login",
                            $api_secret, true));
                        $subAcc = array_get($account, 'subaccount', '');

                        //登录
                        $login = [
                            "op" => "login",
                            "args" => [
                                "key" => $account["api_key"],
                                "sign" => $sig,
                                "time" => $time,
                            ],
                        ];

                        if ($subAcc) {
                            $login['args']['subaccount'] = $subAcc;
                        }

                        $connection->send(json_encode($login));

                        //订阅
                        //fill
                        $connection->send('{"op": "subscribe", "channel": "fills"}');
                        //orders
                        $connection->send('{"op": "subscribe", "channel": "orders"}');

                        Timer::add(15, function () use ($connection) {
                            $connection->send('{"op": "ping"}');
                        });

                        //超时检查
                        Timer::add(30, function () use (
                            $connection,
                            &$connections,
                            $account
                        ) {
                            var_dump($connection->lastTime);
                            if ($connection->lastTime < time() - 60 * 5) {
                                var_dump('超时关闭链接 '.$account['id']);
                                unset($connections[$account['id']]);
                                $connection->close();
                            }

                        });

                    };

                    $ws_connection->onMessage = function (
                        $connection,
                        $json
                    ) use (
                        $account
                    ) {
                        var_dump($json);
                        $data = json_decode($json, true);
                        $channel = array_get($data, 'channel', '');
                        $type = array_get($data, 'type', '');

                        if ($channel == 'fills' && $type == 'update') {
                            $connection->lastTime = time();

                        }

                    };

                    $ws_connection->onError = function (
                        $connection,
                        $code,
                        $msg
                    ) {
                        echo "error: $msg\n";
                    };

                    $re = 0;
                    $ws_connection->onClose = function ($connection) use (&$re
                    ) {
//                        sleep(1);
                        var_dump('关闭');
                        var_dump('重连');
//                        var_dump($connection);
//                        // 如果连接断开,则在1秒后重连
//                        $r = $connection->reConnect(1);
//                        var_dump($r);
                    };

                    $ws_connection->connect();
                }
            });
        };

        Worker::runAll();
  • Tinywan 2021-12-28

    关闭连接,需要清除定时器

    Timer::del($_SESSION['auth_timer_id']);
  • vasileon 2021-12-28

    我没有 用gateway,workerman 也能这样用吗?

  • walkor 2021-12-28
    $connection->timer_id = Timer::add(15, function () use ($connection) {
        $connection->send('{"op": "ping"}');
    });
    $connection->onClose = function($connection){
        Timer::del($connection->timer_id);
    };
年代过于久远,无法发表回答
🔝