前言
websocket 是一種html5新的接口,之前服務器推送須要進行ajax等方式進行輪訓,對服務器壓力較高,隨着新標準的推動,使用websocket在推送等方面已是比較成熟了,而且各個
瀏覽器對websocket的支持狀況已經比較好了,只要不是太老古古董,對這些暫時不考慮。
使用websocket的時候,前端使用是比較規範的,js支持ws協議,感受上相似於一個輕度封裝的socket協議,只是之前須要本身維護socket的鏈接,如今可以以比較標準的方法來進行。
總的來講由於前端是js,因此後端對websocket支持最好的是socket.io,在搜索websocket相關的內容的時候感受socket.io對這個的推廣也是很多的,可是如今使用的是python,由於新學習python
事件不長,各個框架都在接觸一點仍是有好處了。
經常使用框架:
●uwsgi
●flask
●tornado
●django
下面幾個都是一個迴音壁程序,也就是接受前端js發過來的websocket信息,而後將websocket再原路返回
前端js:
var s = new WebSocket("%s://%s/foobar/");
s.onopen = function() {}
s.onmessage = function(e) {}
s.onerror = function(e) {}
s.onclose = function(e) {}
s.send(value);
|
這幾條就是經常使用的js使用websocket的代碼,處理邏輯沒有寫,要看完整的看下面uwsgi的官方給的例子,我基本上是照搬的。鏈接回掉,獲取信息回掉,錯誤回掉,關閉回掉,以及發送信息
uwsgi
官方文檔已經很好了,第一個成功執行的websocket程序就是uwsgi,而後才慢慢的前端不變,而後後端找其餘的方案,官方給的例子也是簡單易懂的,例子在websockets_chat_async.py,從這個例子來看,只用uwsgi,須要維護太多的內容,html與python混在一塊兒實在不太好看,所幸這個例子足夠簡單。
flask-uwsgi-websocket
from flask import Flask, request, render_template
from flask.ext.uwsgi_websocket import GeventWebSocket
app = Flask(__name__)
ws = GeventWebSocket(app)
@app.route('/')
def index():
return render_template('index.html')
@ws.route('/foobar')
def echo(wscon):
msg = wscon.receive()
if msg is not None:
wssss.send(msg)
if __name__ == '__main__':
app.run(gevent=100)
|
這裏使用flask自帶python容器進行執行python
web
從上面代碼能夠看到,使用很簡單,其他部分跟普通的flask都沒有區別,只須要在須要更改websocket的url請求修飾符,修飾符的來源是:
1 ws = GeventWebSocket(app) |
很簡單也很強大,前端庫由於邏輯不須要更改,因此感受挺好的,可是這個庫Flask-uWSGI-WebSocket好像有個bug,在用這個庫的時候,前端js持續接收到空的消息而後觸發了onmessage回掉函數,在使用一樣的前端js,其餘後端庫的時候沒有這個問題。
geventwebsocket
from flask import Flask, request, render_template, abort
from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/foobar')
def echo():
if request.environ.get('wsgi.websocket'):
ws = request.environ['wsgi.websocket']
if ws is None:
abort(404)
else:
while True:
if not ws.closed:
message = ws.receive()
ws.send(message)
if __name__ == '__main__':
http_server = WSGIServer(('',5000), app, handler_class=WebSocketHandler)
http_server.serve_forever()
|
這段代碼一樣使用了flask來進行模板,url之類的解析,不一樣之處是再也不使用flask自帶的容器,而是看成一個應用,被gevent裏的一個uwsgiserver容器來調用。
而與普通使用方法不一樣的是注入了handler_class這個類,替換成websocket類型的,具體實現尚未看,可是從邏輯上能夠理解,原來的wsgiserver不理解websocket,因此換一個理解websocket的類來進行處理,
因此在foobar的程序中才能夠從request的環境變量裏獲取websocket鏈接,從這裏來看,websockethandler也對websocket鏈接進行了維護
工做,簡化了不少工做。
須要注意的是,這個庫當前最新版本是0.9.5,網上搜到了一個教程,可是它的版本針對的是0.3.5版本的,這個庫的維護者還進行了變動,其中有些api好像有了變化,須要注意。