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 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题