使用Tornado向客户端发送间歇性更新
我写了一个简单的 Tornado 应用,使用 WebSocket 来管理后台进程(就像 Transmission 的网页界面一样)。有一件事让我困扰,就是状态更新的实现。
我的 WebSocketHandler 只接收来自客户端的消息,执行必要的操作,检查状态,然后把状态发送回客户端。它不会在没有请求的情况下主动发送状态给客户端。
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self):
print('connected')
self.daemon = Daemon()
self.write_message(self.daemon.get_status())
def on_message(self, message):
if message == 'start':
self.daemon.start()
elif message == 'stop':
self.daemon.stop()
self.write_message(self.daemon.get_status())
def on_close(self):
print('disconnected')
我在客户端使用了 JavaScript 的 setInterval 函数来定期请求状态更新,像这样:
ws = new WebSocket("ws://localhost:8080/websocket");
ws.onopen = function () {
setInterval(function() {
if (ws.bufferedAmount == 0)
ws.send('status');
}, 1000);
};
}
那么,如何在服务器端实现相同的效果,让 Tornado 能够主动发送当前状态给客户端,而不阻塞 on_message 方法呢?
1 个回答
7
你可以使用 tornado.ioloop.IOLoop.add_timeout
这个方法,每隔X秒调用一次某个方法来更新客户端的信息:
from tornado.ioloop import IOLoop
from datetime import timedelta
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self):
print('connected')
self.daemon = Daemon()
self.write_message(self.daemon.get_status())
self.schedule_update()
def schedule_update(self):
self.timeout = IOLoop.instance().add_timeout(timedelta(seconds=5),
self.update_client)
def update_client(self):
try:
self.write_message(self.daemon.get_status())
finally:
self.schedule_update()
def on_close(self):
IOLoop.instance().remove_timeout(self.timeout)
print('disconnected')