Tornado defines the tornado.websocket.WebSocketHandler class to handle requests for WebSocket connections. Application developers should inherit this class and implement its open(), on_message(), and on_close() functions.
WebSocketHandler.open() function: The Tornado framework will call this function when a new WebSocket connection is established. In this function, developers can use the get_argument() function to obtain the parameters submitted by the client as in get(), post() and other functions, and use get_secure_cookie/set_secure_cookir to operate cookies, etc.
WebSocketHandler.on_message(message) function: After establishing the WebSocket link, the Tornado framework will call this function when a message from the client is received. Usually, this is the core function of server-side WebSocket programming, which processes the received message accordingly.
WebSocketHandler.on_close() function: When the WebSocket connection is closed, the Tornado framework will call this function. In this function, you can query the reason for closing by accessing self.close_code and self.close_reason.
In addition to these three entry functions automatically called by the Tornado framework, WebSocketHandler also provides two developers to actively operate WebSocket functions.
WebSocketHandler.write_message(message,binary=False) function: used to write messages to the client relative to this link.
WebSocketHandler.close(code=None,reason=None) function: actively close the WebSocket link. The code and reason are used to tell the client why the link is closed. The parameter code must be a numeric value, and reason is a string.
The following is the Tornado WebSocket program that continuously pushes time messages to the client:
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()
The above code is parsed as follows:
The global variable dictionary clients is defined to save all client information that establishes a WebSocket connection with the server. The key of the dictionary is the client id, and the value is a tuple consisting of the id and the corresponding WebSocketHandler instance
IndexHandler is an ordinary page processor used to report to the client Render the homepage index.html on the client side. This page contains the WebSocket client program.
MyWebSocketHandler is the core processor in this example, inherited from tornado.web.WebSocketHandler. The open() function saves all client connections to the clients dictionary; on_message() is used to display messages sent by the client; on_close() is used to remove closed WebSocket links from Removed from clients dictionary.
The function sendTime() runs in a separate thread, polls all clients in clients every 1 second and pushes time messages to the clients through the MyWebSocketHandler.write_message() function.
In this example, only two routes are configured in the tornado.web.Application instance, pointing to IndexHandler and MyWebSocketHandler respectively, which are still started and run by Tornado IOLoop.
The above is the detailed content of Introduction to WebSocket server-side programming in Python's Tornado. For more information, please follow other related articles on the PHP Chinese website!