python tornado websocket_基于Python Tornado框架的websocket服务
WebSocket 是 HTML5 開始提供的一種在單個 TCP 連接上進行全雙工通訊的協(xié)議。
Tornado中定義了tornado.websocket.WebSocketHandler來處理websocket請求。
Tornado框架的安裝以及入門這里就不說了,想入門tornado的請移步我的另一篇文章奧小飛:基于Python的Tornado框架入門?zhuanlan.zhihu.com
WebSocketHandler類中方法簡介
open()
當websocket連接建立后被調(diào)用
on_message(message) *該方法必須被重寫
當收到客戶端發(fā)送的消息時被調(diào)用
on_close()
當websocket連接關(guān)閉后被調(diào)用
write_message(message, binary=False)
向客戶端發(fā)送消息,message可以是字符串或字典(字典會被轉(zhuǎn)為json)。若binary為False,則message以utf8編碼發(fā)送;二進制模式(binary=True)時,可發(fā)送任何字節(jié)碼。
close()
關(guān)閉websocket連接
check_origin(origin)
判斷源origin,對于符合條件(返回判斷結(jié)果為True)的請求源origin允許其連接,否則返回403。可以重寫此方法來解決WebSocket的跨域請求(如始終return True)。
websocket demo
import tornado.ioloop
import tornado.web
import tornado.websocket
class ConnectHandler(tornado.websocket.WebSocketHandler) :
def check_origin(self, origin) :
'''重寫同源檢查 解決跨域問題'''
return True
def open(self) :
'''新的websocket連接后被調(diào)動'''
self.write_message('Welcome')
def on_close(self) :
'''websocket連接關(guān)閉后被調(diào)用'''
def on_message(self, message) :
'''接收到客戶端消息時被調(diào)用'''
self.write_message('new message :' + message) # 向客服端發(fā)送
class MainHandler(tornado.web.RequestHandler) :
def get(self) :
self.write("Hello world")
class Application(tornado.web.Application) :
def __init__(self) :
handlers = [
(r'/index', MainHandler),
(r'/ws', ConnectHandler)
]
tornado.web.Application.__init__(self, handlers)
if __name__ == "__main__" :
app = Application()
app.listen(8000)
tornado.ioloop.IOLoop.current().start()
前端頁面demo
Tornado WebSocketConnect websocket:
function sendMsg() {
if ("WebSocket" in window) {
var ws = new WebSocket("ws://localhost:8000/ws");
ws.onopen = function() {
ws.send("Hello");
};
ws.onmessage = function (evt) {
alert(evt.data);
};
}
}
這個demo創(chuàng)建了一個websocket服務(wù)并監(jiān)聽8000端口,在瀏覽器建立連接之后會觸發(fā)open()方法向瀏覽器推送“welcome”消息,在收到瀏覽器發(fā)送的消息后會觸發(fā)on_message()方法向瀏覽器推送“new message :”消息。
到此為之,一個簡單的websocket應用已經(jīng)可以了。
但是這個demo太過于簡單,他只實現(xiàn)了在建立連接時和收到消息時的一些操作,并沒有體現(xiàn)websocket的主要作用(實時推送數(shù)據(jù))。
websocket demo 進階
import tornado.ioloop
import tornado.web
import tornado.websocket
class ProStatus():
connector = {} # 記錄當前連接的user
def user_connect(self, user):
if user not in self.connector:
self.connector[user] = set()
def user_remove(self, user):
self.connector.remove(user)
def trigger(self, message):
''' 向所有被記錄的客戶端推送最新內(nèi)容 '''
for user in self.connector:
user.write_message(message)
class ReceiveHandler(tornado.web.RequestHandler):
def get(self):
msg = self.get_argument('msg', '')
ProStatus().trigger(msg) # 接收到消息之后推送
class ConnectHandler(tornado.websocket.WebSocketHandler):
def check_origin(self):
'''重寫同源檢查 解決跨域問題'''
return True
def open(self):
'''新的websocket連接后被調(diào)動'''
ProStatus().user_connect(self) #用戶連接后記錄
self.write_message('Welcome')
def on_close(self):
'''websocket連接關(guān)閉后被調(diào)用'''
ProStatus().user_remove(self) # 斷開連接后remove
def on_message(self, message):
'''接收到客戶端消息時被調(diào)用'''
self.write_message('new message :' + message)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello world")
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r'/index', IndexHandler),
(r'/ws', ConnectHandler),
(r'/receive', ReceiveHandler)
]
tornado.web.Application.__init__(self, handlers)
if __name__ == "__main__":
app = Application()
app.listen(8000)
tornado.ioloop.IOLoop.current().start()
問題
心跳包
如果websocket隔一段時間不推送數(shù)據(jù),那么前端的連接就會自動斷開 所以前端建立websocket連接時,需要加入心跳包機制。 當然心跳包不單單是為了解決該問題,也是為了解決各種意外斷開的情況,心跳包很有必要。 心跳包的原理就是每隔一定的時間檢查websocket連接是否斷開,在沒有斷開的情況下隔一定的時間給服務(wù)端發(fā)送一條消息,這條消息要確保服務(wù)端可以回應,如果斷開則進行重連。至于前端具體怎么實現(xiàn)心跳包的代碼請自行百度。
總結(jié)
以上是生活随笔為你收集整理的python tornado websocket_基于Python Tornado框架的websocket服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中exception_Java中
- 下一篇: python函数和类的区别_Python