Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PlayFramework 2.0 Javaと WebSocketでつくる リアルタイムMVC Webアプリケーション

19,956 views

Published on

JavaOne Tokyoの時の資料です。http://www.oracle.co.jp/javaone/2012/timetable/index.html
Blogにて補足説明があったりします。
http://blog.greative.jp/

Published in: Technology
  • やりたいことの資料
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

PlayFramework 2.0 Javaと WebSocketでつくる リアルタイムMVC Webアプリケーション

  1. 1. PlayFramework 2.0 Javaと WebSocketでつくる リアルタイムMVC Webアプリケーション 原 一浩 @kara_d
  2. 2. 原 一浩 @kara_d NetBeans / SublimeText 2
  3. 3. 何してる人? Greative is Great Creative デザイントレンド、統計、システム
  4. 4. 本日のセッション内容https://github.com/karad/PlayWebSocketReversi 4
  5. 5. 本日のセッション内容 サンプルダウンロードURLhttps://github.com/karad/PlayWebSocketReversi 5
  6. 6. 目次 ➡ PlayFrameworkとWebSocketの概要 ➡ WebSocketアプリ制作の概要 • Play 1.2.x • Play 2.0 ➡ サンプル:Reversiの実装とデモ ➡ まとめhttps://github.com/karad/PlayWebSocketReversi 6
  7. 7. Play Frameworkとはhttps://github.com/karad/PlayWebSocketReversi 7
  8. 8. PlayFrameworkとは ➡ オープンソース(zenexity製) ➡ non Servlet、non XML ➡ ステートレス ➡ MVCフレームワーク ➡ ホットデプロイ ➡ ノンブロッキング IO ➡ HTTPマッピング ➡ テスト環境 ➡ シェルサポートhttps://github.com/karad/PlayWebSocketReversi 8
  9. 9. PlayFramework 1.2.xまで ➡ テンプレートはGroovy ➡ フルスタック ➡ JPA拡張によるORM ➡ Javaベース ➡ Pythonによるシェル ➡ Scalaモジュールhttps://github.com/karad/PlayWebSocketReversi 9
  10. 10. PlayFramework 2.0 ➡ テンプレートはScala ➡ モジュール型 ➡ 一部ORM選択可能 • JavaはEBean • ScalaはAnormやScalaQuery ➡ Scalaベース ➡ SBTによるビルドシステム • 従来のplayコマンドに相当 ➡ Akkaによる非同期処理 ➡ Java/Scalaサポートhttps://github.com/karad/PlayWebSocketReversi 10
  11. 11. PlayFramework 2.0 more... ➡ ドキュメントが整備 ➡ サンプルが豊富 ➡ CoffeeScriptサポート ➡ LESSサポート ➡ Google Clojure Compilerサポート ➡ ヘルパー機能https://github.com/karad/PlayWebSocketReversi 11
  12. 12. どちらを使うべきか? ➡ 安心の1.2.x • 大量のサードパーティモジュール • バグフィックスが進んでいる • 業務で使用実績 ➡ 挑戦の2.0 • モジュールは、あまりない • 出たばかりで、まだバグ多い • 業務実績などもこれから アプリの互換性は、ほぼありませんhttps://github.com/karad/PlayWebSocketReversi 12
  13. 13. ニュース ➡ 最近本家のMLがごたごたしてた ➡ 今後1.2系はメンテナンスモードに • つまり1.3は出ない • 1.2.5は月末に出るっぽい ➡ 2.0は、JavaとScala両方を今後サポートしていく ➡ 1.2系をforkする人も? ➡ 1.2系と2.0ではサイトを分ける ➡ 今後はプロジェクトのテンプレートはgiter8でhttps://github.com/karad/PlayWebSocketReversi 13
  14. 14. Play 2.0 Overviewhttps://github.com/karad/PlayWebSocketReversi 14
  15. 15. Play 2.0フォルダ ➡ app ➡ logs • controllers ➡ project • models ➡ public • views ➡ conf • images • javascripts • application.conf • stylesheets • routes ➡ target • IDEを使う人には大事https://github.com/karad/PlayWebSocketReversi 15
  16. 16. Play2.0のサイト構築、基本の流れ(Java) ➡ モデルの構築 • テスト:Unit Test ➡ コントローラーの構築 • テスト:Functional Test ➡ ビューの構築 • テスト:Selenuimベースのfluentleniumhttps://github.com/karad/PlayWebSocketReversi 16
  17. 17. モデル ➡ ORMとしてEBeanを採用 ➡ findやバリデーション(Constraints.*)に対応 @Entity public  class  User  extends  Model{        @Id        public  Long  id;                @Constraints.Required        public  String  name; }https://github.com/karad/PlayWebSocketReversi 17
  18. 18. コントローラ ➡ 基本、Resultを返す public  class  Application  extends  Controller  {    public  static  Result  index()  {        return  ok(index.render());    } }https://github.com/karad/PlayWebSocketReversi 18
  19. 19. レイアウト ➡ レイアウトとビューの区別はない ➡ 呼び出しによる入れ子構造 @(title:  Html,  nav:  String  =  "")(content:  Html) <!DOCTYPE  html> <html>    <head><title>@title</title></head>    <body>        <h1>@title</h1>                @content    </body> </html> main.scala.htmlhttps://github.com/karad/PlayWebSocketReversi 19
  20. 20. ビューテンプレート ➡ main.scala.htmlを呼び出す ➡ 引数と内容(content) @main(Html("Samples"))  {    <p>Hello!</p> } index.scala.htmlhttps://github.com/karad/PlayWebSocketReversi 20
  21. 21. リアルタイム通信サーバの これまでhttps://github.com/karad/PlayWebSocketReversi 21
  22. 22. Flashでのリアルタイム通信 ➡ Adobe Flash Communication Server ➡ Adobe Flash Media Server Real Time Messaging Protocol(RTMP) ➡ Red5 • http://www.red5.org/ • Javaで作られている • オープンソースhttps://github.com/karad/PlayWebSocketReversi 22
  23. 23. WebSocketとはhttps://github.com/karad/PlayWebSocketReversi 23
  24. 24. WebSocketは、W3CとIETFが策定 ➡ 元々はHTML5の一部 ➡ 双方向の通信技術 ➡ AjaxやCommetよりも自然に双方向通信 ➡ コネクション後、専用のプロトコルで通信 • ハンドシェイク • ws:もしくはwss:※ ➡ 最終仕様は、RFC6455。対応は下記 • IE 10 Platform Preview 5※ • Firefox 11 • Google Chrome 16 • Safari 最新※https://github.com/karad/PlayWebSocketReversi 24
  25. 25. WebSocket未対応ブラウザへhttps://github.com/karad/PlayWebSocketReversi 25
  26. 26. web-socket-js ➡ https://github.com/gimite/web-socket-js • Google Chrome 4 or later, Firefox 6 or later • Firefox 3 to 5, Internet Explorer 8, 9 + Flash Player 10 or laterhttps://github.com/karad/PlayWebSocketReversi 26
  27. 27. PlayFrameworkでの利用 ➡ ダウンロードしたら、 • public/javascripts/ に「swfobject.js」「web_socket.js」 • public/swfs/ に「WebSocketMain.swf」 • 配置し、JavaScript側で呼び出せるようにしたら終わりhttps://github.com/karad/PlayWebSocketReversi 27
  28. 28. JavaScriptでのWebSocketの接続方法 WEB_SOCKET_SWF_LOCATION  =  "SWFを配置したパス"; WEB_SOCKET_DEBUG  =  false; var  socket; socket  =  new  WebSocket( @routes.Application.game().webSocketURL(request)) ➡ Flashを介している点が異なる ➡ こうすることで未対応ブラウザでも動作可能https://github.com/karad/PlayWebSocketReversi 28
  29. 29. JavaScriptのWebSocketのAPI ➡ socket = WebSocket(url, protocols) ➡ socket.send() ➡ socket.close() イベントハンドラ ➡ socket.onmessage ➡ socket.onopen ➡ socket.onerror ➡ socket.onclosehttps://github.com/karad/PlayWebSocketReversi 29
  30. 30. WebSocket通信の確認にはChromeが便利https://github.com/karad/PlayWebSocketReversi 30
  31. 31. PlayFrameworkと WebSockethttps://github.com/karad/PlayWebSocketReversi 31
  32. 32. Play1.2.3 ➡ hybi-00 • Chrome 14までサポート Play1.2.4 ➡ hybi-10 • バージョン8 • Chrome 16までサポート パッチ(Lighthouse 1240 patch) ➡ RFC6455 • 最新版に対応https://github.com/karad/PlayWebSocketReversi 32
  33. 33. パッチ(Lighthouse 1240 patch)の当て方 ➡ 該当のパッチを当てる • https://github.com/playframework/play/pull/438 を参照 • framework/src/play/server/PlayHandler.java を修正 ➡ 修正後、antタスクを実行 $  ~/play-­‐1.2.4/framework $  ant   Buildfile:  /Users/harakazuhiro/play-­‐1.2.4/framework/ build.xml ..... BUILD  SUCCESSFUL Total  time:  22  secondshttps://github.com/karad/PlayWebSocketReversi 33
  34. 34. パッチが当たったリビルド版 ➡ バージョン表記が「play! 1.2.x-localbuild」に $  play  run                                                                                             ~                _                        _   ~    _  __  |  |  __  _  _    _|  | ~  |  _  |  |/  _  |  ||  |_| ~  |    __/|_|____|__  (_) ~  |_|                        |__/       ~ ~  play!  1.2.x-­‐localbuild,  http://www.playframework.orghttps://github.com/karad/PlayWebSocketReversi 34
  35. 35. Play以外の対応、ご参考まで •https://github.com/karad/PlayWebSocketReversi 35
  36. 36. WebSocketをフレームワークに載せる意味 ➡ Webアプリケーションとのシームレスな統合 ➡ WebSocketをコントローラーにして設計が容易に ➡ 認証系、データ管理系の実装が楽になる WebSocketアプリケーションとポート ➡ 基本的には、Playが動いているポートになる ➡ Apacheのmod_proxyを経由させている場合は注意https://github.com/karad/PlayWebSocketReversi 36
  37. 37. Play 1.2.4のWebSockethttps://github.com/karad/PlayWebSocketReversi 37
  38. 38. WebSocketController ➡ Staticによるアクション ➡ ルーティングが可能 ➡ InboundとOutboundの2チャンネル ➡ request、params、validation、session ➡ disconnect()で通信の切断 ➡ awaitメソッドで処理の待機 ➡ ビューで、wsプロトコルのURLに • Routesでプロトコルの指定が必要https://github.com/karad/PlayWebSocketReversi 38
  39. 39. InboundとOutbound ➡ Inbound • WebSocketの受信 • WebSocketのソケットオープン中、 inbound.isOpen()がtrue • inbound.nextEvent()にて、イベントを取得 ➡ Outbound • WebSocketの送信 • outbound.send(String string)にて送信 • sendメソッドには、opcodeを指定可能 - outbound.send(byte opcode, byte[] data);https://github.com/karad/PlayWebSocketReversi 39
  40. 40. Outboundあれこれ ➡ テキストフレームは、通常下記みたいな利用をするが、 • outbound.send("quit:ok"); ➡ JSONでも送信が可能。sendJsonを使用する • outbound.sendJson(Object); ➡ 生データ • send( byte opcode, byte[] data)https://github.com/karad/PlayWebSocketReversi 40
  41. 41. テキストフレームのやりとり ➡ 受信 • play.mvc.Http.WebSocketEvent.TextFrameから Matcherを使ってtextDataを取り出す for(String  textData:  TextFrame.match(e._1))  {        ...処理... } ➡ 送信 • outbound.send(String string)を使って送信https://github.com/karad/PlayWebSocketReversi 41
  42. 42. PlayFramework 1.2.4でのサンプルhttps://github.com/karad/PlayWebSocketReversi 42
  43. 43. WebSocket:サーバーとクライアント PlayFramework DB WebSocketハンドシェイク 1 Webサイト WebSocketソケット通信 WebSocket Controller 5 Outboundアプリごとにイベント Model WebSocket Inbound 2デザインが Event Event必要 Join TextFrame Message SocketClose Leave BinaryFrame 4 3https://github.com/karad/PlayWebSocketReversi 43
  44. 44. 全体構成 ➡ クライアント • プロパティを「:」でつないだメッセージ • コマンド : ユーザー : メッセージ • message : name : text ➡ サーバー • WebSocketControllerクラスを継承したChatRoomSocket • ChatRoomSocketには、joinメソッドのみがある • ChatRoomモデル内でチャットのイベントを設定 • inbound.isOpen()の限りループ - Either<WebSocketEvent,ChatRoom.Event> eが評価されない限りは停止https://github.com/karad/PlayWebSocketReversi 44
  45. 45. • 各種イベントにマッチするものがあれば、各処理を実行 - WebSocketのイベントが、TextFrameかつTextFrameがquit - WebSocketのイベントが、TextFrame - Chatroom内のイベントが、ChatRoom.Joinクラス - Chatroom内のイベントが、ChatRoom.Messageクラス - Chatroom内のイベントが、ChatRoom.Leaveクラス - WebSocketのイベントが、SocketClosed public  static  void  join(String  user)  {        while(inbound.isOpen())  {                Either<WebSocketEvent,ChatRoom.Event>  e  =   ここで停止                        await(Promise.waitEither(                                inbound.nextEvent(),                                  roomMessagesStream.nextEvent()));                ...各種処理...        } }https://github.com/karad/PlayWebSocketReversi 45
  46. 46. ChatModelは、イベント管理モデル ➡ 内部にEventクラスというabstractなクラスを用意 ➡ Eventクラスを継承した各種イベントクラス • Joinクラス • Leaveクラス • Messageクラス ChatRoomSocketでのイベント判定 ➡ ChatRoom.Eventクラスをパターンマッチで分岐 • ClassOf(ChatRoom.Join.class).match(e._2) • ClassOf(ChatRoom.Message.class).match(e._2) • ClassOf(ChatRoom.Leave.class).match(e._2)https://github.com/karad/PlayWebSocketReversi 46
  47. 47. Play 2.0のWebSockethttps://github.com/karad/PlayWebSocketReversi 47
  48. 48. WebSocket:サーバーとクライアント DB PlayFramework WebSocketハンドシェイク 1 onReady Model(In) Webサイト WebSocketソケット通信 WebSocket.out Outアプリごと 3 Akkaにイベント Event onReceiveデザインが必要 Join In WebSocket.in 2 Message onMessage Quit 4 onClosehttps://github.com/karad/PlayWebSocketReversi 48
  49. 49. WebSocket用コントローラ ➡ Staticによるアクション ➡ ルーティングが可能 ➡ WebSocketオブジェクトの入出力 • InとOutの2チャンネル ➡ ほとんどの処理はモデルに移動 ➡ onReady()イベントを定義https://github.com/karad/PlayWebSocketReversi 49
  50. 50. WebSocket対応のコントローラー public  static  WebSocket<JsonNode>  game(        final  String  username        )  {        return  new  WebSocket<JsonNode>()  {                public  void  onReady(WebSocket.In<JsonNode>  in,   WebSocket.Out<JsonNode>  out){                        try  {                                  Reversi.join(username,  in,  out);                        }  catch  (Exception  ex)  {                                ex.printStackTrace();                        }                }        }; }https://github.com/karad/PlayWebSocketReversi 50
  51. 51. WebSocket用モデル ➡ 専用のクラス • UntypedActor ➡ Akkaベースの非同期プログラミング ➡ 同期処理は、Awaitメソッド ➡ In.onMessageと、In.onClose ➡ onReceive()イベントを定義 ➡ Out.write()で送信 ➡ メンバーとチャンネルhttps://github.com/karad/PlayWebSocketReversi 51
  52. 52. WebSocket対応のモデルの一部 public  void  onReceive(Object  message)          throws  Exception  {        if  (message  instanceof  Join)  {                //  Received  a  Join  message        }  else  if  (message  instanceof  Message)  {                Message  talk  =  (Message)  message;                notifyAll(                        "talk",  talk.username,  talk.text,                          talk.x,  talk.y,  talk.uuid);        }  else  if  (message  instanceof  Quit)  {                //  Received  a  Quit  message        } }https://github.com/karad/PlayWebSocketReversi 52
  53. 53. AkkaとWebSocketの関係 ➡ WebSocket.In WebSocket.In • メッセージ受け取り時 tell • onMessage(Callback<A> callback) - event ActorRef ➡ Akkaのアクター • イベントの監視、非同期処理 write • onReceive(Object message) ➡ WebSocket.Out WebSocket.Out • 通信の書き出し • write(A frame)https://github.com/karad/PlayWebSocketReversi 53
  54. 54. サンプル:Reversihttps://github.com/karad/PlayWebSocketReversi 54
  55. 55. デモ ➡ https://github.com/karad/PlayWebSocketReversihttps://github.com/karad/PlayWebSocketReversi 55
  56. 56. Reversi作成の手順 ➡ Playアプリケーションの作成 ➡ メッセージフォーマットの設計 ➡ イベントモデルの設計 ➡ コントローラ、モデルの作成 ➡ ルーティングの作成 ➡ ビューの作成 【参考】作業ステップをつけています Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 56
  57. 57. Playアプリケーションの作成(1) ➡ システム企画 • ユーザーは2人(BlackとWhite)の選択 • 盤面をロールオーバーすると相手にも伝わる • 盤面をクリックすると自分の色に変わる • 駒はどこでも配置可能 画面遷移 WebSocket Login Game WS トップページ ゲーム画面 Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 57
  58. 58. Playアプリケーションの作成(2) ➡ トップページ Login • http://URL/ ➡ ゲーム画面 • http://URL/reversi/ Game ➡ WebSocket • ws://URL/reversi/game?username=hoge WS Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 58
  59. 59. Playアプリケーションの作成(3) ➡ コントローラ • app/controllers/Application.java - HTTPリクエストを受けるところ ➡ モデル • app/models/Reversi.java - WebSocket周りのイベント処理を記述 ➡ ビュー • app/views/index.scala.html • app/views/main.scala.html • app/views/reversi.scala.html Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 59
  60. 60. メッセージのフォーマット(JSON)を決める ➡ kind • join、talk、quitの各種フラグ ➡ user • ユーザー名(black or white) ➡ x、y ➡ uuid • 各升目のユニークid ➡ message • thinkOver、thinkOut、black、whiteの各メッセージ Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 60
  61. 61. イベントの種類を決める ➡ 各イベントごとにクラスを作成 ➡ public static class Join(username、channel) … 参加 ➡ public static class Message(username、text、x、y、uuid) … 送信 ➡ public static class Quit(username) … 終了 Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 61
  62. 62. コントローラの作成(1):Application.java ➡ 各種メソッドを実装 ➡ public static Result index() … トップページ • index.scala.html を表示 ➡ public static Result reversi(username) … ゲーム画面 • ゲーム画面用アクション • ユーザー名を取得し、ゲーム画面 reversi.scala.html を表示 Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 62
  63. 63. コントローラの作成(2):Application.java ➡ public static WebSocket<JsonNode> game(final String username) … WebSocket • WebSocket用アクション • 初接続時は、ユーザー名をメンバーとしてJoinメソッドを呼び出し • 2回目以降は、JsonFrameをInboundとして処理 Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 63
  64. 64. モデルの作成(1):Reversi.javaの構成 ➡ static ActorRef game … アクター ➡ Map<String, WebSocket.Out<JsonNode>> members … メンバー一覧 ➡ public static void join(username, in, out) … 参加メソッド ➡ public void onReceive(message) … 受信 ➡ public void notifyAll(kind, user, text, x, y, uuid) … 全員に通知 Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 64
  65. 65. モデルの作成(2) ➡ イベント用のインナークラス用意 • Join public  static  class  Join  { • Message        final  String  username; • Quit        final  WebSocket.Out<JsonNode>  channel;        public  Join(                String  username,                  WebSocket.Out<JsonNode>  channel        )  {                this.username  =  username;                this.channel  =  channel;        } } Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 65
  66. 66. モデルの作成(3) ➡ static ActorRef game … アクター static  ActorRef  game  =      Akka.system().actorOf(new  Props(Reversi.class)); ➡ Map<String, WebSocket.Out<JsonNode>> members … メンバー一覧 Map<String,  WebSocket.Out<JsonNode>>  members  =      new  HashMap<String,  WebSocket.Out<JsonNode>>(); Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 66
  67. 67. モデルの作成(4) ➡ public static void join(username, in, out) … 参加メソッド • 接続を行う最初のみ呼び出される • ユーザー名と、Inbound、Outboundを引数 • Joinクラスのインスタンスをメッセージとしてgameに送信 • InboundのonMessageハンドラを設定 - Messageクラスのインスタンスを送信 • InboundのonCloseハンドラ時を設定 - Quitクラスのインスタンスを送信 Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 67
  68. 68. モデルの作成(5) ➡ public void onReceive(message) … 受信 • 送信されてきたメッセージのクラスによって処理を振分け • Joinクラスだった場合 - メンバーに追加 • Messageクラスだった場合 - Outboundにメッセージを送信 • Quitクラスだった場合 - メンバーからusernameを削除 - 退出のメッセージ Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 68
  69. 69. onReceiveメソッドの抜粋 public  void  onReceive(Object  message)          throws  Exception  {        if  (message  instanceof  Join)  {                //  Received  a  Join  message        }  else  if  (message  instanceof  Message)  {                Message  talk  =  (Message)  message;                notifyAll(                        "talk",  talk.username,  talk.text,                          talk.x,  talk.y,  talk.uuid);        }  else  if  (message  instanceof  Quit)  {                //  Received  a  Quit  message        } }https://github.com/karad/PlayWebSocketReversi 69
  70. 70. モデルの作成(6) ➡ public void notifyAll(kind, user, text, x, y, uuid) … 全員に通知 • 各プロパティをJSON形式で格納 • JSONをメンバー全員に送信 Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 70
  71. 71. ルーティングの設定 ➡ ルーティングは、conf/routesファイルを編集 GET          /                            controllers.Application.index() GET          /reversi              controllers.Application.reversi (username:  String  ?=  null) GET          /reversi/game    controllers.Application.game (username) Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 71
  72. 72. ビュー周りの設定(1):ビューですること ➡ レイアウトの用意 ➡ ログイン画面を用意 ➡ ゲーム画面を用意 ➡ ゲーム用のクラスを用意 ➡ 通信用のJavaScriptを用意 ➡ マウスイベント用のJavaScriptを用意 Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 72
  73. 73. ビュー周りの設定(2) ➡ レイアウトの用意 Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 73
  74. 74. ビュー周りの設定(3) ➡ ログイン画面を用意 Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 74
  75. 75. ビュー周りの設定(4) ➡ ゲーム画面を用意 Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 75
  76. 76. ビュー周りの設定(5) ➡ ゲーム用のクラスを用意 .white .black .thinkOut .thinkOver Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 76
  77. 77. ビュー周りの設定(6) ➡ 通信用のJavaScriptを用意 • WebSocketに接続 • メッセージを受信したら、内容に応じて処理 • kindがtalkなら、駒の配置もしくはロールオーバーの表示 var  chatSocket  =  new  WS("WEBSOCKET") var  receiveEvent  =  function(event)  {    var  data  =  JSON.parse(event.data);    //  各種処理 } chatSocket.onmessage  =  receiveEvent; Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 77
  78. 78. ビュー周りの設定(7) ➡ マウスイベント用のJavaScriptを用意 • mouseover時 - textに"thinkOver" - x座標、y座標、uuidに $(this).attr(id) • mouseout時 - textに"thinkOut"、その他は同じ • click時 - textに"ユーザー名"、その他は同じ ➡ WebSocketとして送信 • chatSocket.send(JSON.stringify(オブジェクト)); Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 78
  79. 79. WebSocket通信中のJSON ➡ コマンドラインにて確認可能 org.codehaus.jackson.node.ObjectNode@8bfaf9f[    _children={kind="talk",  user="black",  x=5,  y=4,  uuid="4_5",  message="thinkOut",  members=["black"]}     _nodeFactory=org.codehaus.jackson.node.JsonNodeFactory @fbf00a9 ]; Restful Make Format Event Scheme Model and Controller Routing Fronthttps://github.com/karad/PlayWebSocketReversi 79
  80. 80. F.javaの話https://github.com/karad/PlayWebSocketReversi 80
  81. 81. F.java:Play 1.2.x ➡ WebSocket周りを見ていくと、必ず当たる壁 ➡ Javaで関数言語的な使い方をサポートするライブラリ • Either - E2、E3、E4、E5まである - Haskel由来? • ArchivedEventStream - イベントのキューとして扱う仕組み • Matcher - パターンマッチ用 • Promise - 非同期処理https://github.com/karad/PlayWebSocketReversi 81
  82. 82. パターンマッチFor文:Play 1.2.x for(String  a:  TextFrame.match(e._1))  {        ...処理... } for(String  a:  TextFrame.and(Equals("quit")) .match(e._1))  {        ...処理... } 明示的なキャストが存在しないので、すべてがタイプセーフであり、コンパイラ によって型チェックが行われます。https://github.com/karad/PlayWebSocketReversi 82
  83. 83. F.javaのMatcher周り:Play 1.2.x ➡ String • 文字列でマッチ ➡ ClassOf • クラスでマッチ ➡ StartsWith • プレフィックスでマッチ ➡ Re • 正規表現パターンでマッチ ➡ Equals • 等価な文字列でマッチhttps://github.com/karad/PlayWebSocketReversi 83
  84. 84. WebSocketEvent周りのMatcher ➡ SocketClosed.match() • WebSocketCloseかどうかでマッチ ➡ TextFrame.match() • WebSocketフレームがバイナリでなく、なおかつtextDataでマッチ ➡ BinaryFrame.match() • WebSocketフレームがバイナリで、binaryDataでマッチhttps://github.com/karad/PlayWebSocketReversi 84
  85. 85. F.java:Play 2.0 ➡ Javaで関数言語的な使い方をサポートするライブラリ • Either - E2相当のみになった • Callback - Callback0、Callback1、Callback2、Callback3まである - コールバックを実現する • ArchivedEventStream - Akkaが肩代わり • Matcher - なくなった • Promise - 独自実装、Akkaとの連携もありhttps://github.com/karad/PlayWebSocketReversi 85
  86. 86. F.javaの利用について ➡ F.javaはバージョンごとに変化が激しい ➡ 現状は読むのみに ➡ WebSocket周りでは必須https://github.com/karad/PlayWebSocketReversi 86
  87. 87. まとめhttps://github.com/karad/PlayWebSocketReversi 87
  88. 88. WebSocketアプリの設計・構築手順 ➡ Playアプリケーションの作成 Restful ➡ メッセージフォーマットの設計 Make Format ➡ イベントモデルの設計 Event Scheme ➡ コントローラ、モデルの作成 Model and Controller ➡ ルーティングの作成 Routing ➡ ビューの作成 Front クラスベースハンドラのイベント駆動プログラム関数型風味 WebSocketは、チャットを作るための機能ではないhttps://github.com/karad/PlayWebSocketReversi 88
  89. 89. WebSocketはどこで役に立つのか? ➡ ログイン以降は、ユーザーによる細かな操作が続く ➡ Ajaxで行ってきた部分の上位バージョンとして ➡ ブラウザで閲覧中にリアルタイム通信が必要なとき ➡ 業務アプリなど、利用人数が限られたサイトでの レスポンスの向上 ➡ Pushstate(Pjax)と組み合わせてみよう Pjaw Pushstate JavaScript with WebSockethttps://github.com/karad/PlayWebSocketReversi 89
  90. 90. 今後の研究課題 ➡ 既存の通信手段とのパフォーマンス比較 ➡ 認証がからむケースのセキュアなWebSocket ➡ WebSocketのデータを保存のベストプラクティス ➡ イベントの登録管理をもっとスマートに ➡ PlayにおけるWebSocketの負荷の調査 ➡ サーバー構成の研究 ➡ ネームスペースの実装(Socket.IO)https://github.com/karad/PlayWebSocketReversi 90
  91. 91. ありがとうございました PlayFramework + WebSocket の勉強会 もよろしく http://www.facebook.com/groups/313802075344855/ 詳しくは @kara_d までhttps://github.com/karad/PlayWebSocketReversi 91

×