多个龙卷风客户端同时连接到龙卷风服务器

时间:2018-08-01 14:12:00

标签: python python-2.7 websocket client-server tornado

我让我的Tornado客户端连续不断地循环收听我的Tornado服务器,正如此处提到的-http://tornadoweb.org/en/stable/websocket.html#client-side-support。看起来像这样:

import tornado.websocket
from tornado import gen

@gen.coroutine
def test():
    client = yield tornado.websocket.websocket_connect("ws://localhost:9999/ws")
    client.write_message("Hello")

    while True:
        msg = yield client.read_message()
        if msg is None:
            break
        print msg

    client.close()

if __name__ == "__main__":
    tornado.ioloop.IOLoop.instance().run_sync(test)

我无法使多个客户端实例连接到服务器。第二个客户端在连接到服务器之前总是等待第一个客户端进程结束。从Websockets with Tornado: Get access from the "outside" to send messages to clientsTornado - Listen to multiple clients simultaneously over websockets开始,服务器的设置如下。

class WSHandler(tornado.websocket.WebSocketHandler):

    clients = set()

    def open(self):
        print 'new connection'
        WSHandler.clients.add(self)

    def on_message(self, message):
         print 'message received %s' % message
         # process received message
         # pass it to a thread which updates a variable
         while True:
             output = updated_variable
             self.write_message(output)

    def on_close(self):
        print 'connection closed'
        WSHandler.clients.remove(self)

application = tornado.web.Application([(r'/ws', WSHandler),])

if __name__ == "__main__":
     http_server = tornado.httpserver.HTTPServer(application)
     http_server.listen(9999)
     tornado.ioloop.IOLoop.instance().start()

但是这没有用-出于某种原因,即使我成功建立了第一个连接,第二个连接也无法连接,即甚至没有添加到客户端集中。

我最初认为while True不会阻止服务器接收和处理更多的客户端,但是这样做的话,如果没有多个客户端可以连接。如何在不使用while True的情况下从内部线程发送回不断更新的信息?

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

要在while循环中向客户端写入消息,可以在循环内使用yield None。这将暂停while循环,然后龙卷风的IOLoop将可以自由接受新连接。

这是一个例子:

@gen.coroutine
def on_message(self):
    while True:
        self.write_message("Hello")
        yield None

答案 1 :(得分:0)

感谢您的回答@xyres!我可以通过在处理过程中将on_message传递给while True类之外的函数的WSHandler方法中启动线程来使其工作。我认为,这允许该方法在Tornado的IOLoop外部运行,从而解除新连接的阻塞。

这是我的服务器现在的样子:

def on_message(self, message):
    print 'message received %s' % message
    sendThread = threading.Thread(target=send, args=(self, message))
    sendThread.start()

def send(client, msg):
    # process received msg
    # pass it to a thread which updates a variable
    while True:
        output = updated_variable
        client.write_message(output)

send是在类外部定义的函数,它为我执行所需的计算,并写回到while True内部的客户端。