dqqyp90576 2016-05-11 10:12
浏览 99

PHP WebSocket异步任务

I have the following scenario: I have a WebSocket running with Ratchet (PHP WebSocket) I use the onMessage() callback function to handle incomming data and respond accordingly. If I get the 'start-broadcast' message via the WebSocket I have to start a loop which will send out a broadcast message to all connected clients on the WebSocket every 0.2 sec. So I need to make a loop which can do this, but I can't put it into the onMessage() function, as this will block, and I won't be able to receive any more messages via the WS. If I get the 'stop-broadcast' message via the WebSocket I have to stop the broadcast loop.

So basically I need a way to start and stop this loop, and have this loop running parallel to the WebSocket loop so it doesn't block up.

Problems: The Socket->send() method I'm pretty sure is not thread-safe, so I need to make sure that the WS loop and my broadcast loop are not trying to send a message at the same time.

Possible approaches I have considered:

  • ReactPHP/Promise
    Somehow use this to make an async function inside which I have a loop. I have no experience with Promise, and I don't know if it can do what I need.

  • Running a spearate PHP-CLI process, and use ZMQ for inter-process communication between the WS instance and the Broadcast loop.
    With this I could send message back and forth from the websocket, and I could send a message to start or stop the broadcast, also I could send a message from the broadcast loop to the WS loop to send out a message to the WS clients.

  • Using pthreads
    Spawn a new Thread for the broadcast loop, this can be killed when I want it to stop. I'm pretty sure I'll have to make sure the Socket is only used by one thread at a time, so I'll have handle that somehow.

My question is, which approach should I take, and are there any examples or tutorials for the suggested approach?

  • 写回答

1条回答 默认 最新

  • duanshan1511 2016-05-11 13:05
    关注

    If I get you right:

    • You get in a web-socket - command "start"
    • After receiving the request, you want to start broadcasting with 0.2 seconds interval
    • If you will come - command "stop", you need to stop broadcasting

    Maybe I misunderstood the problem, but it's a bad idea, getting client requests start and stop brodcasting (what if everyone will send a "start command"?)

    In general, I would recommend using ZMQ. This is the most scalable solution. (It is best to separate the services)

    • You start the server.
    • Waiting for commands from ZMQ, that you need to start broadcasting.
    • Once you get a command of ZMQ, create a timer with 0.2 second intervals and broadcasts
    • As soon as you get "command" stop in ZMQ - kill the timer.

    OR

    • Your start the server ZMQ PUB and start brodcasting
    • Yout start web-socket
    • You give command start and start receive ZMQ SUB messages
    • You give command stop and stop receive ZMQ SUB messages

    If you want a pub/sub service. Then simply create a Timer and have a list of who to broadcast. Client send "subscribe", and receive messages. Good idea use Redis for storing data between processes (WebSocket - ZMQ)

    You need read ZMQ PHP DOC, before using ZMQ and see reactphp/zmq lib

    评论

报告相同问题?

悬赏问题

  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记