Python Tornado之WebSocket聊天室
阿新 • • 發佈:2018-12-26
專案背景
最近有個血壓專案,需要用到python tornado+websocket+com通訊,所以會逐漸寫出來。
之前弄的是Springboot2的ws,SpringBoot2.0整合WebSocket,實現後臺向前端推送資訊,現在由於java com口通訊沒有python好用,所以改用Python這套。
WebSocket連線
WebSocket和Http輪詢的都是客戶端和伺服器之間是持久通訊的方式,使用情況可根據場景進行優化選擇,Http輪詢一般可以跟快取很好結合,Ws連線一般可以更快相應並從後端往前端推送。
WebSocket使得客戶端和伺服器之間的資料交換變得更加簡單,允許服務端主動向客戶端推送資料。在WebSocket API中,瀏覽器和伺服器只需要完成一次握手,兩者之間就直接可以建立永續性的連線,並進行雙向資料傳輸。
TornadoWebSocket模組
Tornado在websocket模組中提供了一個WebSocketHandler類,這個類提供了和已連線的客戶端通訊的WebSocket事件和方法的Handler。
- open方法,新的WebSocket連線開啟時被呼叫。
- on_message方法:連線收到新訊息時被呼叫。
- on_close方法:客戶端關閉時被呼叫。
- write_message方法:向客戶端傳送訊息時被呼叫。
- close方法:關閉連線時呼叫。
chat-server.py(服務端程式碼)
# coding:utf-8 import tornado.web import tornado.ioloop import tornado.httpserver import tornado.options import os import datetime from tornado.web import RequestHandler from tornado.options import define, options from tornado.websocket import WebSocketHandler define("port", default=2222, type=int) class IndexHandler(RequestHandler): def get(self): self.render("chat-client.html") class ChatHandler(WebSocketHandler): users = set() # 用來存放線上使用者的容器 def open(self): self.users.add(self) # 建立連線後新增使用者到容器中 for u in self.users: # 向已線上使用者傳送訊息 u.write_message(u"[%s]-[%s]-進入聊天室" % (self.request.remote_ip, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) def on_message(self, message): for u in self.users: # 向線上使用者廣播訊息 u.write_message(u"[%s]-[%s]-說:%s" % (self.request.remote_ip, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), message)) def on_close(self): self.users.remove(self) # 使用者關閉連線後從容器中移除使用者 for u in self.users: u.write_message(u"[%s]-[%s]-離開聊天室" % (self.request.remote_ip, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) def check_origin(self, origin): return True # 允許WebSocket的跨域請求 if __name__ == '__main__': tornado.options.parse_command_line() app = tornado.web.Application([ (r"/", IndexHandler), (r"/chat", ChatHandler), ], static_path = os.path.join(os.path.dirname(__file__), "static"), template_path = os.path.join(os.path.dirname(__file__), "template"), debug = True ) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) tornado.ioloop.IOLoop.current().start()
template\chat-client.html(客戶端程式碼)
如果是通過http web訪問,請放在chat-server.py
目錄下的template\chat-client.html
,如果是檔案直接訪問,就直接拖到瀏覽器訪問即可。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>聊天室</title> </head> <body> <div id="contents" style="height:500px;overflow:auto;"></div> <div> <textarea id="msg"></textarea> <a href="javascript:;" onclick="sendMsg()">傳送</a> </div> <!-- jQuery --> <script src="https://cdn.staticfile.org/jquery/3.3.1/jquery.min.js"></script> <script type="text/javascript"> var ws = new WebSocket("ws://127.0.0.1:2222/chat"); ws.onmessage = function(e) { $("#contents").append("<p>" + e.data + "</p>"); } function sendMsg() { var msg = $("#msg").val(); ws.send(msg); $("#msg").val(""); } </script> </body> </html>