JasonYeung 2019-06-28
Tornado定义了tornado.websocket.WebSocketHandler类用于处理WebSocket链接的请求,应用开发者应该继承该类并实现其中的open()、on_message()、on_close()函数。
除了这三个Tornado框架自动调用的入口函数,WebSocketHandler还提供了两个开发者主动操作WebSocket函数。
下面是持续为客户端推送时间消息的Tornado WebSocket程序:
import tornado.ioloop
import tornado.web
import tornado.websocket
from tornado import gen
from tornado.options import define,options,parse_command_line
import asyncio
clients=dict()#客户端Session字典
class IndexHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@gen.coroutine
def get(self):
print("123")
self.render("index.html")
class MyWebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self, *args, **kwargs): #有新链接时被调用
self.id=self.get_argument("Id")
self.stream.set_nodelay(True)
clients[self.id]={"id":self.id,"object":self}#保存Session到clients字典中
def on_message(self, message):#收到消息时被调用
print("Client %s received a message:%s"%(self.id,message))
def on_close(self): #关闭链接时被调用
if self.id in clients:
del clients[self.id]
print("Client %s is closed"%(self.id))
def check_origin(self, origin):
return True
app=tornado.web.Application([
(r'/',IndexHandler),
(r'/websocket',MyWebSocketHandler),
])
import threading
import time
class SendThread(threading.Thread):
# 启动单独的线程运行此函数,每隔1秒向所有的客户端推送当前时间
def run(self):
# tornado 5 中引入asyncio.set_event_loop,不然会报错
asyncio.set_event_loop(asyncio.new_event_loop())
import datetime
while True:
for key in clients.keys():
msg = str(datetime.datetime.now())
clients[key]["object"].write_message(msg)
print("write to client %s:%s" % (key, msg))
time.sleep(1)
if __name__ == '__main__':
#启动推送时间线程
SendThread().start()
parse_command_line()
app.listen(8888)
#挂起运行
tornado.ioloop.IOLoop.instance().start()解析上述代码如下: