前言
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好像有了變化,需要注意。