我的服务器可以访问通过TCP套接字接收实时更新的API(在广播模式下使用ZeroMQ)。
我想建立一个网络服务,向网站上的人显示这些更新。要转发这些更新,通过WebSockets与所有客户端的持续连接似乎是最佳解决方案。
我对如何单独执行这些操作有一个好主意,但是如何在一个Python服务器应用程序中有效地将这两者结合起来呢?
我目前在伪代码中的想法是这样的:
while True:
acceptNewWebSocketConnections()
update = receiveUpdateZeroMQ()
sendMessageToAllWebSockets(update)
哪种类型的Python库会支持这种模型,如何在防止拥塞的同时实现它?
答案 0 :(得分:2)
作为mguijarr所说的替代方法,您可以在IOLoop中将Tornado与zmq一起使用。
IOLoop基本上可以检查套接字是否可以读取,以及何时调用给定的回调。它运行在一个线程上,但由于它几乎没有时间只是“等待”,它通常更快!
将龙卷风与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()
答案 1 :(得分:0)
我建议使用gevent为所有连接设置一个事件循环,
因为zmq的Python绑定支持gevent(import zmq.green as zmq
)和你
还有一个gevent websockets实现:gevent-websocket;由于WSGI,gevent与许多Web服务器兼容。