python - 多个 tornado 客户端同时连接到 tornado 服务器
python - Multiple tornado clients simultaneously connecting to tornado server
我有我的 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 clients and 。
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
的情况下从我的内部线程发回不断更新的信息?
如有任何帮助,我们将不胜感激!
要在while 循环中向客户端写入消息,可以在循环内使用yield None
。这将暂停 while 循环,然后 Tornado 的 IOLoop 将可以自由接受新连接。
这是一个例子:
@gen.coroutine
def on_message(self):
while True:
self.write_message("Hello")
yield None
感谢@xyres 的回答!我能够通过在 on_message
方法中启动一个线程来使其工作,该线程将处理和 while True
交给 WSHandler
class 之外的函数。我相信这允许方法 运行 在 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
是在 class 外部定义的函数,它为我执行所需的计算并在 while True
.
内部写回客户端
我有我的 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 clients and
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
的情况下从我的内部线程发回不断更新的信息?
如有任何帮助,我们将不胜感激!
要在while 循环中向客户端写入消息,可以在循环内使用yield None
。这将暂停 while 循环,然后 Tornado 的 IOLoop 将可以自由接受新连接。
这是一个例子:
@gen.coroutine
def on_message(self):
while True:
self.write_message("Hello")
yield None
感谢@xyres 的回答!我能够通过在 on_message
方法中启动一个线程来使其工作,该线程将处理和 while True
交给 WSHandler
class 之外的函数。我相信这允许方法 运行 在 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
是在 class 外部定义的函数,它为我执行所需的计算并在 while True
.