simple-swoole / simps

🚀 A simple, lightweight and high-performance PHP coroutine framework.
https://simps.io
Apache License 2.0
469 stars 48 forks source link

demo中订阅程序过几十分钟后就收不到publisher发布的消息了 #20

Closed addls closed 3 years ago

addls commented 4 years ago

刚订阅时能正常收到消息,运行几十分钟后就收不到消息了: https://simps.io/#/zh-cn/mqtt/client?id=%e8%ae%a2%e9%98%85

sy-records commented 4 years ago

recv失败了?打印对应的errCodeerrMsg

addls commented 4 years ago

errCode: 60 errMsg: Operation timed out

sy-records commented 4 years ago

用dev-master试下,这里改过一次没发版 https://github.com/simple-swoole/simps/blob/master/src/Client/MQTTClient.php#L143

addls commented 4 years ago

是使用的dev-master,如图。strlen换了下位置,否则会报错: Whoops\Exception\ErrorException : Uncaught TypeError: strlen() expects parameter 1 to be string, bool given。 QQ20200921-120810

sy-records commented 4 years ago

好吧,我下午看看

sy-records commented 4 years ago

你swoole什么版本,客户端的配置代码也一起发下

addls commented 4 years ago

Swoole: 4.5.4 Simps: 1.0.4

Broker是rabbitMQ 3.8.7

$config = [
            'host' => config('servers.rabbitmq.host'),
            'port' => config('servers.rabbitmq.port'),
            'time_out' => config('servers.rabbitmq.time_out'),
            'username' => config('servers.rabbitmq.username'),
            'password' => config('servers.rabbitmq.password'),
            'client_id' => config('servers.rabbitmq.client_id'),
            'keepalive' => 10,
        ];

        try {
            \Co\run(function () use ($config) {
                $client = new MQTTClient($config);

                while (!$client->connect(true)) {
                    \Swoole\Coroutine::sleep(3);
                    $client->connect(true);
                }

                $topics['v1/devices/me/telemetry'] = 0;
                $timeSincePing = time();
                $client->subscribe($topics);
                while (true) {
                    $buffer = $client->recv();
                    Log::info('TelemetrySubscribe', [$buffer]);
                    if ($buffer && $buffer !== true) {
                        $timeSincePing = time();
                    }

                    if (isset($config['keepalive']) && $timeSincePing < (time() - $config['keepalive'])) {
                        $buffer = $client->ping();
                        if ($buffer) {
                            echo '发送心跳包成功' . PHP_EOL;
                            $timeSincePing = time();
                        } else {
                            $client->close();
                            break;
                        }
                    }
                }
            });
        } catch (\Exception $e) {
            Log::error('onMqPublish', [
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
        }
RABBITMQ_HOST=10.168.2.102
RABBITMQ_PORT=1883
RABBITMQ_TIMEOUT=5
RABBITMQ_USERNAME=test
RABBITMQ_PASSWORD=test
RABBITMQ_CLIENT_ID=TP1
sy-records commented 4 years ago

用master还能复现问题吗?这里应该直接会异常掉

addls commented 4 years ago

是的,你那边不能重现?

sy-records commented 4 years ago

只是超时,recv默认用的connect的超时时间,你调大些应该就可以了

addls commented 4 years ago

我晚上试试

addls commented 4 years ago

测试了下,发现问题在于,当发送消息的数量接近100条时(使用MQTTBox连续点击publish),subscribe程序就会卡住收不到消息了。

sy-records commented 4 years ago

publish了什么信息,qos几?sub有返回响应吗?

addls commented 4 years ago

QQ20200923-123126

sy-records commented 4 years ago

对端的问题,你可以用php代码实现client和server进行测试是否复现,复现了把代码贴出来。