Tornado WebSocketHandler 可以异步接收消息吗?
Can a Tornado WebSocketHandler receive messages asynchronously?
在 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 服务器端的日志也反映了这一点。
那么,我的问题是:
- 为什么每条消息都按发送顺序读取和返回?
- 是否可以规避这种排队行为?怎么样?
- 我是不是完全遗漏了一些基本的东西?
请注意,这不是真实代码,而是合理的复制品。
您绝不能在 IOLoop 线程上 运行 "long, blocking calls",因为那样会阻塞其他一切。 sleep
调用(或它代表的任何内容)必须被重写为异步的或移交给另一个线程(这对于 concurrent.futures.ThreadPoolExecutor
来说相当容易)。有关详细信息,请参阅 http://www.tornadoweb.org/en/stable/faq.html#why-isn-t-this-example-with-time-sleep-running-in-parallel。
在 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 服务器端的日志也反映了这一点。
那么,我的问题是:
- 为什么每条消息都按发送顺序读取和返回?
- 是否可以规避这种排队行为?怎么样?
- 我是不是完全遗漏了一些基本的东西?
请注意,这不是真实代码,而是合理的复制品。
您绝不能在 IOLoop 线程上 运行 "long, blocking calls",因为那样会阻塞其他一切。 sleep
调用(或它代表的任何内容)必须被重写为异步的或移交给另一个线程(这对于 concurrent.futures.ThreadPoolExecutor
来说相当容易)。有关详细信息,请参阅 http://www.tornadoweb.org/en/stable/faq.html#why-isn-t-this-example-with-time-sleep-running-in-parallel。