- Play Framework 2.3
- jQuery 2.1.3
jQueryは公式サイトからダウンロードしましょう。ダウンロードしたファイルはプロジェクト配下の \public\javascripts にコピーします。
さて今回はできるだけシンプルなサンプルを心がけました。特に何かの役に立つものではないですが、仕組みの理解を優先したつもりです(が分かりにくかったらゴメンなさい・・・)。
まずはアクセス方法から。
--------------------------------------------------
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
# Home page
GET / controllers.Application.index()
GET /message controllers.Application.message()
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(path="/public", file)
--------------------------------------------------
/messageを追加しました。これで"ws://localhost:9000/message"でWebSocket接続が可能になります。(localhostの部分は適当に読み替えてください。)
# This file defines all application routes (Higher priority routes first)
# ~~~~
# Home page
GET / controllers.Application.index()
GET /message controllers.Application.message()
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(path="/public", file)
--------------------------------------------------
/messageを追加しました。これで"ws://localhost:9000/message"でWebSocket接続が可能になります。(localhostの部分は適当に読み替えてください。)
--------------------------------------------------
@(message: String)
@main("WebSocket Sample") {
<p>@message</p>
<div id="text"></div>
<p></p>
<input type="button" value="Start" onClick="start()">
<input type="button" value="Stop" onClick="stop()"><p>
<form name="form">
<input type="text" name="message" value="サンプルテキスト">
<input type="button" value="Send" onClick="send()">
</form>
}
--------------------------------------------------
今回はStartボタンでWebSocket接続を行い、Sendボタンでテキストボックスの文字列をサーバに送信、StopボタンでWebSocketを切断するといった操作を実現します。
--------------------------------------------------
var connection = null;
function start() {
$("#text").text("");
connection = new WebSocket("ws://localhost:9000/message");
connection.onopen = function() {
log("connected.");
}
connection.onerror = function(event) {
log("error.");
}
connection.onclose = function(event) {
log("closed.");
}
connection.onmessage = function(event) {
log(event.data);
}
}
function stop() {
connection.close();
}
function send() {
connection.send(document.form.message.value);
}
function log(message) {
$("#text").append(message + "<br>");
}
--------------------------------------------------
ここで・・・まだURLをベタ書きしてます・・・。うまく置き換えれるはずなのですが、まだちゃんとやってないです。
ちなみにログ的に動作状況を確認するために文字列はボタンの上部分のdivタグ内にテキストを追加していってます。
最後はコントローラ部分。ここがPlay2でWebSocketするときの肝の部分ですね。
--------------------------------------------------
package controllers;
import play.Logger;
import play.libs.F.Callback;
import play.mvc.Controller;
import play.mvc.Result;
import play.mvc.WebSocket;
import views.html.index;
public class Application extends Controller {
public static Result index() {
return ok(index.render("WebSocket Sample."));
}
public static WebSocket message() {
return new WebSocket() {
@Override
public void onReady(final WebSocket.In in, final WebSocket.Out out) {
Logger.debug("connected.");
in.onMessage(new Connection(out));
}
};
}
public static class Connection implements Callback {
private WebSocket.Out out;
public Connection(WebSocket.Out out) {
this.out = out;
}
@Override
public void invoke(String event) {
Logger.debug(event);
for (int i=0; i<5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.write(event);
}
}
}
}
--------------------------------------------------
index()で最初の画面を表示します。まー特に変わったところはないです。
message()が問題のWebSocketの接続を受けるメソッドです。index()と異なりWebSocketを返します。このときにWebSocket.Inにその後のメッセージを受信するためのコールバックオブジェクトを登録し、返信用のWebSocket.Outオブジェクトを保存しておきます。
コールバックオブジェクトではメッセージ受信用のハンドラをオーバーライドします。このサンプルでは受け取った文字列を1秒ごとに5回クライアントに返送しています。この部分を実際の処理に書き換えるといろいろ出来そうですね。
あとはもう少しコードをキレイにしたり切断時の処理のことを考えておけばそれなりに使えそうです。いやーそれにしても世の中便利になったもんだ。