pythonのgeventとやらでwebsocket
webでチャットがしたい。出来ればリアルタイムにやりたい。面倒なのは嫌だ。 調べてみたら結構楽だった。
使ったのはgeventというライブラリ。 ネットワークプログラミングのためのライブラリらしいです。wsgi対応みたいなので、多分公開するのも簡単。試してないけど。
で、こいつにはgevent-websocketというライブラリだかなんだかがあるようで、ただしくはそっちを使いました。 まあどちらも入れなきゃいけないようなので、適当に。
サーバーのソースがこんな感じ。
from geventwebsocket.handler import WebSocketHandler
from gevent import pywsgi
ws_list = set()
def chat_handle(environ, start_response):
    ws = environ['wsgi.websocket']
    ws_list.add(ws)
    print 'enter:', len(ws_list), environ['REMOTE_ADDR'], environ['REMOTE_PORT']
    while True:
        msg = ws.receive()
        if msg is None:
            break
        remove = set()
        for s in ws_list:
            try:
                s.send(msg)
            except Exception:
                remove.add(s)
        for s in remove:
            ws_list.remove(s)
    print 'exit:', environ['REMOTE_ADDR'], environ['REMOTE_PORT']
    ws_list.remove(ws)
def myapp(environ, start_response):  
    path = environ['PATH_INFO']
    if path == '/': 
        start_response('200 OK', [('Content-Type', 'text/html')])  
        return open('index.html').read()
    elif path == '/chat':  
        return chat_handle(environ, start_response)
    else:
        start_response('404 Not Found.', [('Content-Type', 'text/plain')])  
        return 'not found'
if __name__ == '__main__':
    server = pywsgi.WSGIServer(('localhost', 8080), myapp, handler_class=WebSocketHandler)
    server.serve_forever()
かなりシンプル。 大事なのは渡されたenvironに入ってるwsgi.websocketを読み書きしてるだけ。
で、HTML。サーバーと同じディレクトリに置いてください。
<!DOCTYPE html>
<html>
    <head>
        <script>
            function init() {
                ws = new WebSocket('ws://localhost:8080/chat');
                ws.onmessage = function(e) {
                    document.getElementById('holder').innerHTML += '<p>' + e.data + '</p>\n';
                };
                document.getElementById('send').onclick = function send(){
                    ws.send(document.getElementById('message').value);
                    document.getElementById('message').value = ''
                };
            }
        </script>
        <style>
            #sender {
                position: fixed;
                bottom: 0;
                left: 0;
                right: 0;
                border-top: 1px solid black;
            }
        </style>
    </head>
    <body onload="init();">
        <div id="holder"></div>
        <div id="sender">
            <input type="text" id="message" size=80 value="text">
            <button id="send">send</button>
        </div>
    </body>
</html>
なんかかなり適当なコードだけど、気にしないで。
サーバー立ち上げて、localhost:8080にアクセスしてみてください。チャット出来るはず。 簡単だよねー。素敵。
参考: