在python方面,我创建了一个WebSocketHandler
。
from tornado import gen
from tornado.escape import json_decode
from tornado.websocket import WebSocketHandler
class Echo(WebSocketHandler):
...
@gen.coroutine
def on_message(self, message):
message = json_decode(message)
response = yield self.do_echo(message)
self.write_message(response)
@gen.coroutine
def do_echo(self, message):
# emulate long, blocking call
sleep(randint(0, 5))
raise gen.Return(message)
在javascript方面,我同时启动多个客户端(不同的浏览器):
var ws = new WebSocket('ws://localhost:5000/echo');
ws.onmessage = function (evt) {
console.log(JSON.parse(evt.data));
}
for (var i = 0; i < 10; i++) {
var msg = {
messageid: i,
payload: 'An echo message.'
};
ws.send(JSON.stringify(msg));
}
正如预期的那样,所有客户大致在同一时间完成。但是,每个客户端收到的消息都按照发送它们的确切顺序(messageid
)进行记录,就好像WebSocketHandler
正在排队消息一样。服务器端的Python日志也反映了这一点。
那么,我的问题是:
请注意,这不是真正的代码,而是合理的传真。
答案 0 :(得分:1)
你必须永远不要在IOLoop线程上运行“长时间阻塞调用”,因为这会阻止其他所有内容。那个sleep
调用(或者它所代表的任何东西)必须被重写为异步或者移交给另一个线程(concurrent.futures.ThreadPoolExecutor
相当容易)。有关详情,请参阅http://www.tornadoweb.org/en/stable/faq.html#why-isn-t-this-example-with-time-sleep-running-in-parallel。