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