tornado 官方文档给出了一个聊天室的websocket 案例,需要在客户端发动消息,然后推送给聊天室中的所有人。 从后台定时推送处理后的数据到前端需要稍微改动下。
class WsHandler(tornado.websocket.WebSocketHandler):
waiters = set()
cache =[]
cache_size = 200
def check_origin(self, origin):
return True
async def open(self):
self.waiters.add(self)
self.write_message('Welcome '+ str(self))
await self.put_msg()
def on_close(self):
self.write_message("Goodbye " + str(self))
self.waiters.remove(self)
@classmethod
def update_cache(cls,msg):
cls.cache.append(msg)
if len(cls.cache) > cls.cache_size:
cls.cache = cls.cache[-cls.cache_size:]
@classmethod
def send_update(cls,msg):
for waiter in cls.waiters:
try:
waiter.write_message(msg)
except:
logging.error("error sending message", exc_info = True)
@classmethod
async def put_msg(cls):
while True:
rectime = str(datetime.now())[:19]
cputotal = 100 - psutil.cpu_percent(0)
cls.send_update(str(rectime) + " " + str(cputotal))
await asyncio.sleep(2)
def on_message(self, message):
'''接收到客户端消息时被调用'''
json_msg = {"id": str(uuid.uuid4()), "body":message}
self.update_cache(json_msg)
self.send_update(json_msg)
在websocket open 时,调用一个方法来实现定期推送数据。 因为tornado是异步模式,所以这个put_msg方法要用异步调用,一般这种情况需要实现一个while 循环,在循环中获取数据经过处理后发送给所有连接的前端节点。