32
WebSocket + Akka (Remote) + Play framework 2.1 Java 原 一浩 @kara_d SPDY+WS勉強会(仮)

WebSocket+Akka(Remote)+Play 2.1 Java

Embed Size (px)

DESCRIPTION

SPDY+WS勉強会で発表した資料です

Citation preview

Page 1: WebSocket+Akka(Remote)+Play 2.1 Java

WebSocket+ Akka (Remote) +

Play framework 2.1 Java

原 一浩 @kara_d

SPDY+WS勉強会(仮)

Page 2: WebSocket+Akka(Remote)+Play 2.1 Java

自己紹介

2

原 一浩ハラ カズヒロ

グレーティブ合同会社代表

Playはじめて&もくもく会主宰Scala conferenceスポンサー日本Play frameworkユーザー会参加コワーキングスペース茅場町Co-Edo

http://greative.jp/

( @kara_d )

Page 3: WebSocket+Akka(Remote)+Play 2.1 Java

アジェンダ➡ Play 2.1 JavaとWebSocket➡ Akkaについて➡ WebSocketとAkkaとJava➡ Akka Remoteによる並列、分散処理

※今回は、文字数節約のためにPlay 2.1 JavaのことをPlayと呼ぶことに しました

3

Page 4: WebSocket+Akka(Remote)+Play 2.1 Java

Play 2.1 JavaとWebSocket

Page 5: WebSocket+Akka(Remote)+Play 2.1 Java

Play frameworkとは?➡ Zenexity(フランスの会社)➡ Typesafe(Scala総本山、Martin Odersky氏など)

特徴とされているもの➡ ノンブロッキングIO採用➡ パワフルなコンソールとシンプルなビルドツール➡ ステートレスかつウェブ向き➡ 型安全的➡ IDEサポート➡ Java/Scalaで開発➡ モジュール的の高いフルスタックFW

5

Page 6: WebSocket+Akka(Remote)+Play 2.1 Java

Play バージョン 2.xについて➡ ~2012/2

Play 1.x:Javaベース、Groovyテンプレート、 Hibernate独自拡張、Pythonによるビルドシステム、WebSocketは1.2から

➡ 2012/2Play 2.0:Scalaベース、Java/Scala両方で開発可能、JavaのORMはEBean、Scalaテンプレート、SBTによるビルド

➡ 2013/2Play 2.1:フォルダやビルド構成の見直し、各種ライブラリのバージョンアップ、Scalaのバージョンアップ

6

Page 7: WebSocket+Akka(Remote)+Play 2.1 Java

PlayでWebSocketコンテンツの魅力➡ MVCFWを使ったのWebアプリケーションにちょこっと導入とかもできちゃう普通のコントローラーと同じ感覚でWebSocketの処理を書けるルーティングも同じ感じ

➡ 必要に応じて分散処理を組めるAkkaつかう

7

Page 8: WebSocket+Akka(Remote)+Play 2.1 Java

シンプルなWebSocketサンプル➡ ハンズオンでやったもの

8

Page 9: WebSocket+Akka(Remote)+Play 2.1 Java

SPDYサポート周り➡ Using SPDY and HTTP transparently using Netty | Smartjava.org http://www.smartjava.org/content/using-spdy-and-http-transparently-using-netty

➡ Nettyが3.3.1でSPDYに対応したぽいのでがんばればできるのかも

9

Page 10: WebSocket+Akka(Remote)+Play 2.1 Java

Akkaについて

Page 11: WebSocket+Akka(Remote)+Play 2.1 Java

Akkaってなに?➡ Typesafe社の開発➡ アクターモデルをベースにした非同期処理、並行処理➡ リモーティングによる分散処理➡ アクターの管理と耐障害性(let-it-crash)➡ 設定との分離によって位置透過性を担保➡ ソフトウェアトランザクショナルメモリ➡ 非同期、スケジューリング、イベント処理にも使える

11

Page 12: WebSocket+Akka(Remote)+Play 2.1 Java

ActorRef … アクターのキモ➡ Akkaのアクターへの参照➡ アクターモデル

並行計算の数学的モデルの一種

アクターモデルの基本は「全てのものはアクターである」という哲学

アクターは並行的に受信するメッセージに対応した以下のような振る舞いを備えた計算実体(Computational Entity)である

他のアクターとの通信は非同期に発生する

- wikipedia

12

ActoronReceive(o) DoActor

onReceive(o) ( )Object

Page 13: WebSocket+Akka(Remote)+Play 2.1 Java

アクターへのメッセージパッシング➡ tellとaskがある

tellなげっぱ。fire-and-forget。

void tell(Object msg, ActorRef sender)

askFuture型でかえってくる

Future ask(ActorRef actor, Object message, long timeout)

13

Page 14: WebSocket+Akka(Remote)+Play 2.1 Java

PlayとWebSocketとAkka➡ Playでは、WebSocketを使う場合、ハンドシェイク時、通信が発生した時のイベント送出に利用あと、裏でいろいろ動く非同期系

14

Page 15: WebSocket+Akka(Remote)+Play 2.1 Java

WebSocketとAkkaとJava

Page 16: WebSocket+Akka(Remote)+Play 2.1 Java

Play 2.1 Java + WebSocketの全体像

16

ClientJavaScript

HandshakeControllerWebSocket<T>onReady()

ModelActorRef

onReceive(o)

InonMessage()onClose()

JsonNode

tell(Object message)

WebSocket

OutJsonNode

Page 17: WebSocket+Akka(Remote)+Play 2.1 Java

Play WebSocket with Akkaまとめ➡ 通信は双方向かつリアルタイムに行われる(普通)➡ WebSocketにはInとOutがある

WebSocket.In<JsonNode> inWebSocket.Out<JsonNode> out

➡ JSON or String(つまりTextFrame)で通信をしている(BinaryFrameとか、MixedFrameとかも)

➡ 非同期なイベントを管理するためにAkkaを使う(使わないこともできる)

17

Page 18: WebSocket+Akka(Remote)+Play 2.1 Java

Akkaのイベントシステムについて(1)➡ Akka Javaは、UntypedActorをよく使う➡ UntypedActorはObjectでメッセージを送受信する➡ Scala版では、パターンマッチですっきり書ける

※Scala版はObject型というわけではない

18

def  receive  =  {    case  Join(username)  =>  {  ...  }    case  Talk(username,  text)  =>  {  ...  }    case  Quit(username)  =>  {  ...  }}

Page 19: WebSocket+Akka(Remote)+Play 2.1 Java

Akkaのイベントシステムについて(2)➡ Akka Javaでは、メッセージがObjectなので、普通に書くとこうなる

19

if(message  instanceof  Join)  {        Join  join  =  (Join)message;        ...}  else  if(message  instanceof  Talk)    {        Talk  talk  =  (Talk)message;        ...}  else  if(message  instanceof  Quit)    {        Quit  quit  =  (Quit)message;        ...}  else  {        unhandled(message);}

Page 20: WebSocket+Akka(Remote)+Play 2.1 Java

Akka Javaのメッセージパッシング判定(1)➡ イベントはTypesafe Enumで定義しておく

WebSocketのイベントはだいたい決まっている

20

public  enum  WebSocketEvent  {        JOIN        {  String  init()  {  return  ...        }  },        MESSAGE  {  String  init()  {  return  ...        }  },        QUIT        {  String  init()  {  return  ...        }  };        abstract  String  init();}

Page 21: WebSocket+Akka(Remote)+Play 2.1 Java

Akka Javaのメッセージパッシング判定(2)➡ イベント処理をScalaっぽく書く

Javaではイベント用のinterfaceと、PlayのOptionと、Enumを使ってこうなる

21

Option<Message>  event  =  EventUtil.getEvent(message);if(event.isDefined()){        switch  (event.get().getEventType())  {                case  JOIN:        ...  break;                case  MESSAGE:  ...  break;                case  QUIT:        ...  break;                default:  unhandled(message);  break;        }}

Page 22: WebSocket+Akka(Remote)+Play 2.1 Java

非同期で渡すCallback、Functionなどは?➡ Java 8を待つ

仕事でもOKになるのは当分先かな...

➡ IntelliJ IDEAでごまかして見る仕事でも使えるw

22

Page 23: WebSocket+Akka(Remote)+Play 2.1 Java

しかし…、MVCWebフレームワークベースのWebアプリケーションにWebSocketが加わると、すんごい重くなるのでは。

23

Page 24: WebSocket+Akka(Remote)+Play 2.1 Java

そこで…、Akka Remoteによる並列、分散処理

Page 25: WebSocket+Akka(Remote)+Play 2.1 Java

Akka Remote➡ Akka Remoteを使うと、Akka Actorをリモートでアクセス可能になる

➡ Play 2.1の場合

➡ 通信は、TCPやUDPが使える➡ セキュリティ対応も可能

25

"com.typesafe.akka" %% "akka-remote" % "2.1.2"

Page 26: WebSocket+Akka(Remote)+Play 2.1 Java

Akka Remoteはこれができる(1)➡ 設定により、アクターの所在を決めることができる

26

master  {        akka  {                actor  {                        provider  =  "akka.remote.RemoteActorRefProvider"                }                remote  {                        transport  =  "akka.remote.netty.NettyRemoteTransport"                        netty  {                                hostname  =  "127.0.0.1"                                port  =  0                        }                }        }}

Page 27: WebSocket+Akka(Remote)+Play 2.1 Java

Akka Remoteはこれができる(2)➡ アクターへのリファレンス先が別ホストとかに!

27

//  アクターのインスタンスpublic  final  static    ActorRef  actor  =          system.actorFor("akka://[email protected]:2258/user/master2");

Page 28: WebSocket+Akka(Remote)+Play 2.1 Java

Akka Remoteはこれができる(3)➡ プログラム上からの利用はおなじ!

28

//  アクターへの問い合わせactor.tell(  [メッセージオブジェクト]  ,  getSelf());

Page 29: WebSocket+Akka(Remote)+Play 2.1 Java

すごくシンプルなサンプル➡ Playが2つ起動

それぞれにアクターがいる

➡ 片方のPlayにアクセスがあるとURLに書かれたパラメータを、もう一方のアクターにtellする

➡ 送受信したメッセージがそれぞれターミナルに表示

29

Page 30: WebSocket+Akka(Remote)+Play 2.1 Java

Akka RemoteとWebSocket➡ WebSocketは、どうしても接続用サーバに負荷がかかるモデルとかログとか別サーバーに、プログラマブルな形で透過的に使いたい

➡ リアルタイムアプリケーションは、同時にいろいろなことが発生する並行処理をAkka Remoteに非同期にまかせる

30

Page 31: WebSocket+Akka(Remote)+Play 2.1 Java

Actor RemoteによるMVCの分散

31

Database

Actor

Log

Actor

Model

Actor

Controller

ActorMessage

Message

ViewModel

Actor

Page 32: WebSocket+Akka(Remote)+Play 2.1 Java

ありがとうございました!!次のPlayはじめて&もくもく会は

4月14日(日) 10時00分 - 18時00分[Play部屋] 第11回 Play 2.1 はじめて&もくもく会

日本Playframeworkユーザー会 http://playframeworkja.doorkeeper.jp/events/3414

参加料:会場利用代 ¥1,000