Python WebSocket のチャットサンプルに、MongoDB 保存を付け加えました
Python で WebSocket を利用したサンプルプログラムは、検索してみると、簡単なチャットプログラムとしてとても多く見つかります。
今回は、そのようなチャットのサンプルプログラムを参照しながら、そのメッセージを MongoDB に保存するように書き加えてみます。さらに、初期表示に最新5件のメッセージを表示するようにします。
サンプルプログラムでは、フレームワークに Flask を利用したものがよくみられたので、それにならって Flask を利用することにし、また、WSGI Server に gevent を利用します。
次のプログラムは、ws-chat.py でセーブしました。
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()
そして、テンプレートを利用します。
ws-chat.py をセーブしたディレクトリの直下に templates ディレクトリを作成して ws-chat.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>
MongoDB アクセスは別のモジュールで「Mosquitto の payload を MongoDB に保存してみる」で作成しました。
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 ws-chat.py
サーバー環境は、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 チャットサンプルを改造」