1

我的服务器可以访问通过 TCP 套接字接收实时更新的 API(在广播模式下使用 ZeroMQ)。

我想构建一个网络服务,在网站上向人们显示这些更新。为了转发这些更新,通过 WebSockets 与所有客户端的持续连接似乎是最好的解决方案。

我对如何分别做这些事情有一个好主意,但是如何有效地将这两者结合到一个 Python 服务器应用程序中呢?

我目前在伪代码中的想法是这样的:

while True:
    acceptNewWebSocketConnections()
    update = receiveUpdateZeroMQ()
    sendMessageToAllWebSockets(update)

什么样的 Python 库会支持这种模型,如何在防止拥塞的同时实现它?

4

2 回答 2

2

作为 mguijarr 所说的替代方案,您可以在 IOLoop 中将 Tornado 与 zmq 一起使用。

IOLoop 基本上是检查套接字是否可供读取,以及何时调用给定的回调。它在单个线程上运行,但由于它几乎没有浪费时间在“等待”上,它通常更快!

将 tornado 与 ZMQ 一起使用非常简单,因此您所描述的架构可以是这样的:

from zmq.eventloop import zmqstream, ioloop
import tornado.web
from tornado import websocket

class MyBroadcastWebsocket(websocket.WebSocketHandler):
    clients = set()

    def open(self):
        self.clients.add(self)

    @classmethod
    def broadcast_zmq_message(cls, msg):
        for client in cls.clients:
            client.write_message('Message:' + str(msg)) # Send the message to all connected clients

    def on_close(self):
        self.clients.remove(self)

def run():
    ioloop.install()
    my_stream = zmqstream.ZMQStream(my_zmq_socket) # i.e. a pull socket
    my_stream.on_recv(MyBroadcastWebsocket.broadcast_zmq_message) # call this callback whenever there's a message

if __name__ == "__main__":
    application = tornado.web.Application([
        (r"/websocket", MyBroadcastWebsocket),
    ])
    application.listen(8888)
    ioloop.IOLoop.instance()

字面意思就是这样!您可以在zmqtornado的文档中查看更多信息。

于 2014-08-29T08:08:28.213 回答
0

我建议使用gevent为所有连接设置一个事件循环,因为 zmq 的 Python 绑定支持 gevent ( import zmq.green as zmq) 并且您还可以在此处使用 gevent websockets 实现:gevent-websocket;由于 WSGI,gevent 与许多 Web 服务器兼容。

于 2013-10-03T20:21:27.670 回答