tornadoでWebSocketサーバを動かしてみる

  1. Tornado で HTTP サーバを用意
  2. HTML ファイルの JS が WebSocket サーバと通信
  3. ブラウザでこの HTML ファイルを表示。
  4. 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 の箇所が書き換われば成功です。

tornado-websocket-demo

References

Leave a comment