Python WebSocket のチャットサンプルに、MongoDB 保存を付け加えました
Python で WebSocket を利用したサンプルプログラムは、検索してみると、簡単なチャットプログラムとしてとても多く見つかります。
今回は、そのようなチャットのサンプルプログラムを参照しながら、そのメッセージを MongoDB に保存するように書き加えてみます。さらに、初期表示に最新5件のメッセージを表示するようにします。
サンプルプログラムでは、フレームワークに Flask を利用したものがよくみられたので、それにならって Flask を利用することにし、また、WSGI Server に gevent を利用します。
次のプログラムは、ws-chat.py でセーブしました。
[python]
import os,sys
import gevent
from gevent import monkey; monkey.patch_all()
from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
from flask import Flask, render_template, request
import time
from datetime import datetime
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + ‘/../model’)
from mchat import (ChatLog, connecter)
app = Flask(__name__)
participants = set()
@app.route(‘/chat’)
def chat():
ws = request.environ.get(‘wsgi.websocket’)
participants.add(ws)
try:
wlist = []
posts = ChatLog.objects.order_by("-id" , "-datetime")[:5]
for post in posts:
wlist.append(post.text)
for value in reversed(wlist):
ws.send(value)
while True:
m = ws.receive()
print "recv message %s" % m
if m is None:
break
for p in participants:
print "send message %s" % m
p.send(m)
now = int(time.mktime(datetime.now().timetuple()))
ChatLog(text=m, user=’WS’, created_at=now).save()
finally:
participants.remove(ws)
return ""
@app.route(‘/’)
def index():
return render_template(‘ws-chat.html’)
if __name__ == "__main__":
connecter()
server = WSGIServer((‘0.0.0.0’,8080), app, handler_class=WebSocketHandler)
server.serve_forever()
[/python]
そして、テンプレートを利用します。
ws-chat.py をセーブしたディレクトリの直下に templates ディレクトリを作成して ws-chat.html でセーブしました。
[html]
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
window.onload = function() {
var data = {};
var s = new WebSocket("ws://127.0.0.1:8080/chat");
s.onopen = function() {
s.send(‘New participant joined’);
};
s.onmessage = function(e) {
$("#out").prepend("<p>" + e.data + "</p>");
};
$(‘#in’).keyup(function(e){
if (e.keyCode == 13) {
var line = $(this).val();
$(this).val(”);
s.send(line);
return false;
}
});
};
</script>
</head>
<body>
<h3>Chat</h3>
<p>Message: <input id="in" /></p>
<div id="out">
</div>
</body>
</html>
[/html]
MongoDB アクセスは別のモジュールで「Mosquitto の payload を MongoDB に保存してみる」で作成しました。
[python]
from mongoengine import *
class ChatLog(Document):
text = StringField(required=True)
user = StringField(required=True)
created_at = LongField(required=True)
def connecter():
con = connect(‘chattest’)
print con
[/python]
実行します。
[bash]
python ws-chat.py
[/bash]
サーバー環境は、ConoHa VPS で、CentOS 6.5 です。
ここへ、Android から接続してすべてを行っています。
Android の VNC クライアントアプリ bVNC Pro からつながるように、Desktop と VNC 環境を作成していますので、これを利用して確認などをおこなっています。
第1回の「Mosquitto の payload を MongoDB に保存してみる」では、Mosquitto の payload を MongoDB に保存しました。
第2回の「MongoDB に保存した Mosquitto の payload を Server-Sent Events で表示してみる」では、HTML5 の Server-Sent Events と PHP でブラウザに表示しました。
今回の第3回は、Python で WebSocket を利用した簡単なチャットプログラムを参考に MongoDB アクセスを書き加えてみました。
第4回は、第3回の Python の WebSocket チャットプログラムを参考にしつつ、ブラウザから POST メソッドで Mosquitto へ Publish し、また、Server-Sent Events でブラウザに表示する方式を Python で試してみます。
「Mosquitto Publish と Server-Sent Events で Python チャットサンプルを改造」