Play frameworkでWebSocketを使う


目次

こんにちは。フリュー モバイル事業部の九岡です。 今回はPlay frameworkのWebSocketサポートをご紹介します。

WebSocket

WebSocketとは、WebブラウザとWebサーバ間でリアルタイムに双方向通信を行うための通信方法です。

ブラウザ-サーバ間のリアルタイムな双方向通信は、これまでもFlashやAppletでソケット通信を使えばできましたが、

  • JavaScriptから直接アクセスできない
  • Webの範囲外であるが故にWebフレームワークが対応しておらず、サーバ側の実装も面倒くさい

という難点がありました。

そこでWebSocketです。

双方向通信の仕様がWebSocketとしてブラウザに取り込まれる事で、実装の敷居が下がりました。

  • 最近流行のHTML5+JavaScriptのクライアントアプリにちょっと手を入れるだけで双方向通信に対応できる
  • 巷のWebフレームワーク等のサポートが始まり、サーバ側の実装コストも低い

Play framework meets WebSocket

さて、本題のPlay frameworkですが、バージョン1.2からWebSocketをサポートしています。

Play frameworkはMVCアーキテクチャに基づいたWebフレームワークですが、

C層にWebSocketControllerというものが追加されました。

これを実装するだけで、既存のWebアプリケーションをさくさくっとWebSocketに対応させることができます。

これまで利用してきたHTTPベースのWebアプリケーションを同居させることができたり、同じModelをWebSocketControllerからも利用することができるなど、相互運用性が高いところもポイントです。

環境

Play framework

バージョン1.2以降

ブラウザ

最近の * Google Chrome * Safari * Mobile Safari Mobile Safariというところがポイントで、実はiPhone/iPad/iPod touchでもWebSocketが使えます。

実装例

双方向通信のイメージが湧くように、WebSocketを利用してWebベースのechoサーバを実装してみます。 仕様は以下のようにします。

  1. テストページから、サーバにメッセージを送信できる
  2. 送信されたメッセージが、サーバからそのまま返送される
  3. 返送されたメッセージがページ内に表示される

View

まず、Viewを作成します。

app/views/Echo/demo.html

id=whatのinput要素にメッセージを入力して、id=sayのボタンをクリックするとメッセージをWebSocket経由でサーバに送信します。 id=messagesのdiv要素に、全メッセージが表示されます。

このコードで@@{ /** */ }となっている部分は、WebSocketの接続先の指定です。

このViewがHTMLとして出力される時には、conf/routseのルート定義に基づいて、

のように置換えられます。

また、

は、sendの引数に渡した文字列をWebSocket経由で送信します。

は、WebSocket経由でサーバからメッセージを受け取る度に実行されます。

がサーバから送信されたメッセージです。

Integration Test

仕様1〜3のテキトウなテストを書きます。

今回はWebSocketというブラウザに依存する機能を通したテストなので、Integration TestをPlayのSeleniumテストケースを使います。

先ほど作成したViewを見ながら、

test/Application.test.htmlに以下の内容を追記してください。

このテストケースでは、

  • /echoを開いた時に、エラーが発生していないこと
  • input要素にメッセージを入力して送信ボタンをクリックすると、しばらく後にメッセージがページ内に表示されること

を検証しています。

2つめのテストでは、メッセージがWebSocketを経由してサーバに送信され、サーバがそれを送り返してページに表示される、ということを期待しています。

作成したテストケースは、

から実行できます。

WebSocketController

テストページの表示と、WebSocketでのメッセージのやり取りのためのコントローラを実装します。

Echo.demoがテストページを表示するメソッドです。

render()により描画されるViewは、先ほど作成したapp/views/Echo/demo.htmlです。

Echo.WebSocketEcho.listenがWebSocket経由のメッセージのやり取りを行うメソッドです。

1コネクションあたり1回呼び出され、接続終了までループでメッセージを待ち続けます。

HTTP用のコントローラとは全く実装方法が違いますね。

routes

conf/routesにHTTP, WebSocket用コントローラへのパスを登録します。

前者はhttp://localhost:9000/echoのようなURLへのHTTPリクエストをEcho.demoへ、

後者はws://localhost:9000/echoのようなURLへのWebSocket接続をEcho.WebSocketEcho.listenへルーティングします。

実行例

では早速実行してみましょう。

ブラウザで以下のURLにアクセスすると、デモページが表示されます。

ポート番号はconf/application.confで設定したものです。

[]1

このように、送信したメッセージがWebSocket経由でechoされてページに表示されます。

また、

から、作成したSeleniumテストケースを実行することができます。

[]2

このように、ブラウザのWebSocket実装を通したテストもブラウザ上で実行できます。

まとめ

この記事では、Play frameworkのWebSocketサポートについて説明しました。

  • WebSocketはWebブラウザとWebサーバの双方向通信のための規格です。
  • Play frameworkでは、WebSocketControllerを実装するだけで既存のWebアプリに双方向通信機能を後づけできます。
  • Play frameworkでWebSocketを利用したechoサーバとテストページを実装しました

Play frameworkなら、WebSocketを活用したWebアプリがさくっと作れそうな気がしますね!(ΦωΦ)

ソースコードはコチラ(GitHub)