- Tornado で HTTP サーバを用意
- HTML ファイルの JS が WebSocket サーバと通信
- ブラウザでこの HTML ファイルを表示。
- WebSocket クライアントが WebSocket サーバにメッセージを送信すると、HTML が書き換わる
というようなシナリオを実現するシンプルなデモを作ってみました。
WebSocket Server
サーバには表題の通り Python Tornado を利用します。
パッケージのインストール
Tornado のビルドには Python のヘッダーファイルが必要です。
以下は RedHat 系でのインストール例です。
$ sudo yum install -y python27-devel $ sudo pip install tornado
コード
クラス Tornado.websocket.WebSocketHandler を継承して WebSocket サーバを実装します。
WebSocket サーバがメッセージを受け取ると、 on_messege ハンドラーが呼びだされます。
import tornado.ioloop import tornado.web import tornado.websocket cl = [] class WebSocketHandler(tornado.websocket.WebSocketHandler): def open(self): if self not in cl: cl.append(self) def on_message(self, message): for client in cl: client.write_message(message) def on_close(self): if self in cl: cl.remove(self) class MainHandler(tornado.web.RequestHandler): def get(self): self.render('test_ws.html') application = tornado.web.Application([ (r"/", MainHandler), (r"/websocket", WebSocketHandler), ]) if __name__ == "__main__": application.listen(8080) tornado.ioloop.IOLoop.current().start()
HTML/JS ファイル
WebSocket 用の JavaScript は HTML ファイル内にベタッと書きます。
WebSocket クライアント送信されたメッセージは
variable : <span id="variable">default</span>
の箇所に反映されます。
<h1>WebSockets Test</h1> <script> var ws; ws = new WebSocket("ws://54.65.113.57:8080/websocket"); ws.onmessage = function(ev) { document.getElementById('variable').innerHTML = ev.data; } </script> variable : <span id="variable">default</span>
WebSocket Client
クライアントには Python 製の websocket-client を利用します。
パッケージのインストール
pip でインストールします。
$ sudo pip install websocket-client
コード
引数で送信メッセージを受け取り、WebSocket につないでメッセージ送信します。
import sys from websocket import create_connection ws = create_connection("ws://localhost:8080/websocket") if len(sys.argv) > 1: message = sys.argv[1] else: message = 'hello world!' print ws.send(message) print ws.recv() ws.close()
実行例
サーバを起動します。
$ python test_ws.py
次にブラウザで HTTP://HOST:8080/ にアクセスします。
この状態で、クライアントプログラムからメッセージ送信します。
$ python test_client.py 'new value' 15 new value
variable
の箇所が書き換われば成功です。