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にアクセスしてみてください。チャット出来るはず。 簡単だよねー。素敵。
参考: