meinheld websocket
こんにちわ、しのまりファンことmopemopeです。
meinheld 0.3よりwebsocketをサポートする予定です。
websocketはmiddleware経由で取得できます。
WebSocketMiddlewareを使うとenvironからwebsocketを取得できます。
シンプルなチャットはこんな感じ。
meinheld/websocket_chat_simple.py at dev · mopemope/meinheld · GitHub
import os from meinheld import server, middleware, websocket participants = set() """ @websocket.WebSocketWSGI def handle(ws): participants.add(ws) try: while True: print "ws.wait()..." m = ws.wait() print "recv msg %s" % m if m is None: break for p in participants: print "send message %s" % m a = p.send(m) print "%s" % a finally: participants.remove(ws) """ def websocket_handle(environ, start_response): ws = environ.get('wsgi.websocket') participants.add(ws) try: while True: print "ws.wait()..." m = ws.wait() print "recv msg %s" % m if m is None: break for p in participants: print "send message %s" % m p.send(m) finally: participants.remove(ws) return [""] def dispatch(environ, start_response): """Resolves to the web page or the websocket depending on the path.""" if environ['PATH_INFO'] == '/chat': return websocket_handle(environ, start_response) else: print "/" start_response('200 OK', [('Content-Type', 'text/html'), ('Content-Length', '814')]) ret = [open(os.path.join( os.path.dirname(__file__), 'templates/websocket_chat.html')).read()] return ret if __name__ == "__main__": server.listen(("0.0.0.0", 8000)) server.run(middleware.WebSocketMiddleware(dispatch))
chromeでしかテストしてないですが動作します。
eventletではdecoratorで指定するのですが、environに埋めたほうが使い勝手がよいだろうということでこうしています。
flask版
meinheld/websocket_chat.py at dev · mopemope/meinheld · GitHub
from flask import Flask, render_template, request from meinheld import server, middleware SECRET_KEY = 'development key' DEBUG=True app = Flask(__name__) app.config.from_object(__name__) participants = set() @app.route('/') def index(): return render_template('websocket_chat.html') @app.route('/chat') def chat(): print request.environ ws = request.environ.get('wsgi.websocket') participants.add(ws) try: while True: print "ws.wait()..." m = ws.wait() print "recv msg %s" % m if m is None: break for p in participants: print "send message %s" % m p.send(m) finally: participants.remove(ws) return "" if __name__ == "__main__": server.listen(("0.0.0.0", 8000)) server.run(middleware.WebSocketMiddleware(app))
非常にシンプルに書けますね。
既存のフレームワークにも簡単に組み込めるので便利です。