我有以下场景:我有一个运行Ratchet的WebSocket(PHP WebSocket)我使用onMessage()回调函数来处理输入数据并相应地做出响应。如果我通过WebSocket获得"start broadcast"消息,我必须启动一个循环,该循环将每0.2秒向WebSocket上所有连接的客户端发送一条广播消息。因此,我需要制作一个可以做到这一点的循环,但我不能将其放入onMessage()函数中,因为这会阻塞,我将无法通过WS接收更多消息。如果我通过WebSocket收到"停止广播"消息,我必须停止广播循环。
因此,基本上我需要一种方法来启动和停止这个循环,并使这个循环与WebSocket循环并行运行,这样它就不会阻塞。
问题:我很确定Socket->send()方法不是线程安全的,所以我需要确保WS循环和我的广播循环不会同时发送消息。
我考虑过的可能方法:
-
ReactPHP/承诺
以某种方式使用它来创建一个异步函数,在该函数中我有一个循环。我没有Promise的经验,我不知道它是否能满足我的需求。 -
运行spearate PHP-CLI进程,并使用ZMQ在WS实例和广播循环之间进行进程间通信
有了这个,我可以从网络套接字来回发送消息我可以发送消息来启动或停止广播,我也可以将消息从广播循环发送到WS循环以发送消息发送给WS客户端。 -
使用pthread
为广播循环生成一个新线程,当我希望它停止。我很确定我必须确保插座一次只被一个线程使用,所以我将以某种方式处理它。
我的问题是,我应该采取哪种方法,建议的方法有什么例子或教程吗
如果我说对了:
- 你进入了一个网络套接字-命令"启动"
- 收到请求后,您希望以0.2开始广播秒间隔
- 如果你要来-命令"停止",你需要停止广播
也许我误解了这个问题,但这是一个坏主意,让客户端请求启动和停止brodcasting(如果每个人都会发送"启动命令"怎么办?)
一般来说,我建议使用ZMQ。这是最具可扩展性的解决方案。(最好将服务分开)
- 您启动服务器
- 等待ZMQ的命令,你需要开始广播
- 一旦获得ZMQ命令,创建一个间隔0.2秒的计时器并进行广播
- 一旦你在ZMQ中得到"命令"停止,就关闭计时器
或
- 您启动服务器ZMQPUB并开始brodcasting
- 您无法启动web套接字
- 您发出命令启动并开始接收ZMQ SUB消息
- 您发出停止命令并停止接收ZMQ SUB消息
如果你想要酒吧/酒吧服务。然后简单地创建一个Timer,并有一个要广播的人的列表。客户端发送"订阅",并接收消息。使用Redis在进程之间存储数据是个好主意(WebSocket-ZMQ)
在使用ZMQ之前,您需要阅读ZMQ PHP DOC,并查看reacthp/ZMQ-lib