workerman\mqtt subscribe订阅问题

iHalo

根据官方示例
在 onWorkerStart的回调中进行创建mqtt客户端,然后进行订阅
但官方是订阅一个topic
我现在的需求是以数组的方式进行多个topic订阅,
数组来源于数据库,
发现命令行运行之后,数据库订阅信息进行更新但是workerman创建的mqtt客户端里面订阅的仍然是之前的数据,
目前解决的办法是手动reload命令行,
请问官方人员和其他有经验的大佬,这个问题如何在不重启命令行的情况下进行处理。
也尝试过如下代码,但不知合不合理。希望官方给予回复。

如上,测试每10秒进行订阅,订阅信息确实能够及时更新了,但是没有测试其他功能是否正常,希望官方给予最佳实践,感谢!

1330 5 1
5个回答

iHalo

刚才测了上述方法,订阅是能更新了,但是onMessage回调没有执行,一直在执行上面的循环。

  • 2548a 2022-04-26

    只要你看过workerman开发必读就不会问这种问题
    7、不要使用exit die sleep语句

    业务执行exit die语句会导致进程退出,并显示WORKER EXIT UNEXPECTED错误。当然,进程退出了会立刻重启一个新的进程继续服务。如果需要返回,可以调用return。sleep语句会让进程睡眠,睡眠过程中不会执行任何业务,框架也会停止运行,会导致该进程的所有客户端请求都无法处理。
    9、业务代码里不要有死循环

    业务代码里不要有死循环,否则会导致控制权无法交还给workerman框架,导致无法接收处理其它客户端消息。

  • iHalo 2022-04-26

    看过开发必读,忘记了。手册来回翻,看一点忘一点。。。

iHalo

@walkor

  • 暂无评论
manbuheiniu

感觉这个逻辑有问题,onConnent是连接回调,不应该在这里面订阅。订阅是阻塞任务。
我认为应该是另起一个进程订阅,收到数据后通知已连接的客户端。客户端连接成功后可以把需要通知的客户端ID放到redis,然后保持在线就可以。订阅进程拿到数据后查redis看需要给哪个客户端推送。
个人理解,不一定对,仅限参考

iHalo

也考虑过使用 Timer 一段时间后执行命令行重启

但这样涉及到liunx用户权限以及操作处理是否成功或者异常等问题,没有深入研究过,测试在Worker的onWorkerReload回调成功执行,但依然觉得并不是最佳实践。

  • 暂无评论
six

onWorkerStart里用定时器

\Workerman\Timer::add(10, function(){
    $this->subscribe(Handle::getSubscribe());
});
  • iHalo 2022-04-26

    感谢回答,我试一下

  • iHalo 2022-04-26

    这个方法可行!感谢。但是不知道是不是会影响onMessage的业务处理,原理我不太明白。

  • walkor 2022-04-26

    死循环影响,因为workerman得不到进程控制权,无法执行onmessage。定时器执行完归还控制权,workerman就可以监听触发onMessage

  • iHalo 2022-04-26

    好的,了解了。大佬还有其他方法推荐吗,或者最佳实践应该怎么做。

  • walkor 2022-04-26

    没有最佳,只有更适合你的,用six的方法就行了。

  • iHalo 2022-04-26

    好的,感谢

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