ChannelClient::publish频繁出现推送不成功情况!

jie365@126.com

知道长连接需要加心跳来维持连接

读源代码发现Channel\Client有自动ping机制,这个ping也是向服务端发送信息的,可以当作是发送心跳数据吗?

既然是发送了心跳,为何出现Channel\Client::publish()失败的情况?

    public static function connect($ip = '127.0.0.1', $port = 2206)
    {
        if (self::$_remoteConnection) {
            return;
        }

        self::$_remoteIp = $ip;
        self::$_remotePort = $port;

        if (PHP_SAPI !== 'cli' || !class_exists('Workerman\Worker', false)) {
            self::$_isWorkermanEnv = false;
        }

        // For workerman environment.
        if (self::$_isWorkermanEnv) {
            if (strpos($ip, 'unix://') === false) {
                $conn = new AsyncTcpConnection('frame://' . self::$_remoteIp . ':' . self::$_remotePort);
            } else {
                $conn = new AsyncTcpConnection($ip);
                $conn->protocol = Frame::class;
            }

            $conn->onClose = [self::class, 'onRemoteClose'];
            $conn->onConnect = [self::class, 'onRemoteConnect'];
            $conn->onMessage = [self::class , 'onRemoteMessage'];
            $conn->connect();

            //自动定时发送ping

            if (empty(self::$_pingTimer)) {
                self::$_pingTimer = Timer::add(self::$pingInterval, 'Channel\Client::ping');
            }
            // Not workerman environment.
        } else {
        ......
        }

        self::$_remoteConnection = $conn;
    }

    /**
     * Ping.
     * @return void
     */
    public static function ping()
    {
        if(self::$_remoteConnection)
        {
            self::$_remoteConnection->send('');
        }
    }
1055 2 0
2个回答

walkor

如何判断失败的?
执行 php start.php connections 能看到所有的连接情况,包括Channel 的连接

  • jie365@126.com 2022-01-14

    A客户端订阅了x事件,publish推送 y事件。
    B客户端定时推送x事件,订阅y事件。

    A能一直能看到B定时推送的x事件,B 有一定概率看不到A推送的y事件。

  • jie365@126.com 2022-01-14

    所以断定应该是A 推送y事件没有成功

  • walkor 2022-01-14

    php start.php connections 看下连接对不对

  • jie365@126.com 2022-01-14

    大佬,这个定时ping可以认为是发送心跳吗?

  • walkor 2022-01-14

  • jie365@126.com 2022-01-14

    [14-Jan-2022 17:30:23 Asia/Shanghai] PHP Warning: stream_socket_client(): php_network_getaddresses: getaddrinfo failed: Name or service not known in /data/www/admin/PushCommandService/vendor/workerman/workerman/Connection/AsyncTcpConnection.php on line 195

    publish的时候报这个错

  • walkor 2022-01-14

    请求的地址错了,域名解析不了

jie365@126.com

/usr/local/php_all/bin/php /data/www/admin/PushCommandService/channel_server.php start -d
启动的channel server

过一段时间后,运行/usr/local/php_all/bin/php /data/www/admin/PushCommandService/channel_server.php connections
显示:

Workerman[/data/www/admin/PushCommandService/channel_server.php] connections
Workerman[/data/www/admin/PushCommandService/channel_server.php] not run

这是啥情况?

查看进程,进程还存在,channel client客户端都能发布、订阅事件
[root@admin ~]# ps -axu |grep channel_server
root 10357 0.0 0.2 323760 16032 ? S 1月13 0:00 WorkerMan: master process start_file=/data/www/admin/PushCommandService/channel_server.php
root 12198 0.0 0.0 112836 2284 pts/0 S+ 15:46 0:00 grep --color=auto channel_server

  • walkor 2022-01-14

    php channel_server.php status 正常么

  • jie365@126.com 2022-01-14

    也是not run

  • walkor 2022-01-14

    可能是pid文件丢失或者被重置了(比如放到代码库里被重置),有设置 Worker::$pidFile 没。没有的话pid默认存在vendor/workerman/下,看下pid文件在不在

  • walkor 2022-01-14

    看下pid文件内容是不是10357

  • jie365@126.com 2022-01-14

    服务器上,$pidFile指定的路径没有了

  • walkor 2022-01-14

    应该是谁删了,pid文件问题你们自己找下吧。

  • jie365@126.com 2022-01-14

    ok,我先解决PID问题,可能是文件发布的时候清除掉了

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