tornado之WebSocket

WebSocket

WebSocket是HTML5規範中新提出的客戶端-服務器通信協議,協議自己使用新的ws://URL格式。javascript

WebSocket 是獨立的、建立在 TCP 上的協議,和 HTTP 的惟一關聯是使用 HTTP 協議的101狀態碼進行協議切換,使用的 TCP 端口是80,能夠用於繞過大多數防火牆的限制。html

WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,容許服務端直接向客戶端推送數據而不須要客戶端進行請求,二者之間能夠建立持久性的鏈接,並容許數據進行雙向傳送。前端

目前常見的瀏覽器如 Chrome、IE、Firefox、Safari、Opera 等都支持 WebSocket,同時須要服務端程序支持 WebSocket。java

1. Tornado的WebSocket模塊

Tornado提供支持WebSocket的模塊是tornado.websocket,其中提供了一個WebSocketHandler類用來處理通信。python

WebSocketHandler.open()

當一個WebSocket鏈接創建後被調用。jquery

WebSocketHandler.on_message(message)

當客戶端發送消息message過來時被調用,注意此方法必須被重寫。web

WebSocketHandler.on_close()

當WebSocket鏈接關閉後被調用。json

WebSocketHandler.write_message(message, binary=False)

向客戶端發送消息messagea,message能夠是字符串或字典(字典會被轉爲json字符串)。若binary爲False,則message以utf8編碼發送;二進制模式(binary=True)時,可發送任何字節碼。後端

WebSocketHandler.close()

關閉WebSocket鏈接。跨域

WebSocketHandler.check_origin(origin)

判斷源origin,對於符合條件(返回判斷結果爲True)的請求源origin容許其鏈接,不然返回403。能夠重寫此方法來解決WebSocket的跨域請求(如始終return True)。

2. 前端JavaScript編寫

在前端JS中使用WebSocket與服務器通信的經常使用方法以下:

var ws = new WebSocket("ws://127.0.0.1:8888/websocket"); // 新建一個ws鏈接 ws.onopen = function() { // 鏈接創建好後的回調 ws.send("Hello, world"); // 向創建的鏈接發送消息 }; ws.onmessage = function (evt) { // 收到服務器發送的消息後執行的回調 alert(evt.data); // 接收的消息內容在事件參數evt的data屬性中 }; 

3. 在線聊天室的小Demo

後端代碼 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=8000, type=int) class IndexHandler(RequestHandler): def get(self): self.render("index.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() 

前端代碼index.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> <script src="{{static_url('js/jquery.min.js')}}"></script> <script type="text/javascript"> var ws = new WebSocket("ws://192.168.114.177:8000/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>
相關文章
相關標籤/搜索