Upload
kouji-matsui
View
796
Download
2
Embed Size (px)
DESCRIPTION
SignalRブートキャンプ 地理冗長の中心でAzure愛を叫ぶin 名古屋2014.3.1 http://www.kekyo.net/2014/03/02/signalr-%e3%83%96%e3%83%bc%e3%83%88%e3%82%ad%e3%83%a3%e3%83%b3%e3%83%97-on-windows-azure%e3%82%a4%e3%83%99%e3%83%b3%e3%83%88/
Citation preview
地理冗長の中心でAzure愛を叫ぶ in 名古屋 2014.3.1 Kouji Matsui (@kekyo2)
SignalR ブートキャンプSignalR ブートキャンプ
自己紹介
Kouji Matsui (@kekyo2)
名古屋のコミュニティ、MiCoCiのメンバーです。
「なごやこわい」のメンバーではありませんw
アーキテクトやってます。あと、スクラム道もはじめました。
リアルタイム通信、始まる
サーバーとクライアントを接続して、何か連携できることがしたいよね!! TCPとかでリアルタイム通信! ゲーム!!
でも、基本、クライアントの人だから、サーバーわかんないんだ、何もかも(遠い目)
「SignalR」ってライブラリを使えば、簡単にリアルタイム通信出来るよ!! サーバーの管理なんて、Windows Azureに任せちゃえばいい!
SignalRが使えると?
SignalRおいしい? それ何?
TCPでソケット繋いでどうとか、通信電文がどうだとか、面倒な事は殆ど自動でやってくれる! → だから、本来実現したかったことに集中出来る!!
ほうほう、それで?
簡単実現!
SignalRがやってくれる事
Jsonによる通信(プレーンではない)
通信手段の自動的な選択HTTPやWebSocketなど
サーバーのメソッドを呼び出す感覚でコードを書けるワ
通信を抽象化
・同報通知も可能・特定端末にだけ送信・グルーピングして送信
サポートする環境は?
Windows PC / IE / Chrome / etc...
Windows Phone / Tablets...Windows Server
さぁ、はじめよう!
SignalR使おうとしたら、OWINって?
Open Web Interface for .NET
ウェブサーバー向けの新しいフレームワーク
えぇー?またフレームワーク増えたの?!
まぁ、そうなんですが、ASP.NET WebFormやMVCとは位置づけがちょっと違います。SignalRはこれに乗っかります。
OWINの詳細は知らなくても大丈夫ですが、どんなものなのか、少しだけ紹介します。
大丈夫、NuGetを使えば簡単に導入できます!
見せてもらう必要がありそうネ、全て取り払った 最小のコードとやらを
いくらNuGetで簡単にライブラリを導入できても、一度にあまりに大量のコードが追加されると、何が何だか... orz
では、「スクラッチ」に近い状態でのコードをお見せします。
論よりOWIN
OWINの導入は超簡単。NuGet一発!”Install-Package Microsoft.Owin.Host.SystemWeb” (2.0.2)
Owin Microsoft.Owin
Microsoft.Owin.Host.SystemWeb
ASP.NETでOWINを動作可能にする
似たようなパッケージが沢山公開されているので、注意!
論よりOWIN
「OWINスタートアップクラス」を追加
スタートアップクラスとOwinを結びつける
Hello! OWIN
IOwinContext – HttpContextの抽象インターフェイス
何がどうなってる?
ASP.NETウェブフォームでは、HttpContextを受け取るまでに、System.Web.UI.Pageからページを生成する必要がありました。
Pageクラスはデカい、ページレンダリングの余分なコードが多い。シンプルではない。例のように、Hello World的コードであっても、非常に大がかりな仕掛けが動作します。
OWINは非常にシンプル。IOwinContextを受け取って動作するまでに必要な、複雑なフレームワーク構造は存在しません。
IOwinContext
OWINでSignalRのセットアップ
NuGetで一発“Install-Package Microsoft.AspNet.SignalR.SystemWeb” (2.0.2)
Owin Microsoft.Owin Microsoft.Owin.Host.SystemWeb
Microsoft.AspNet.SignalR.Core
Microsoft.AspNet.SignalR.SystemWeb
Web.configがおかしい...
2.0.2をNuGetで導入時に、Web.configに不正なエントリーが追加されるので、手動で修正が必要。
アセンブリバージョンの3番目要素を広くする。この例では「99」に設定した
OWINでSignalRのセットアップ
OWINスタートアップクラスで、SignalRにコンテキストを転送する
Microsoft.AspNet.SignalR.Core.dll
Owin.OwinExtensions.MapSignalR()
コンテキストパイプラインをSignalRに転送
準備完了
後はハブとメソッドを決めるだけネ?
何を作る?
ホワイトボードアプリ
Windows Phone・Silverlight・WPFでリアルタイム白板会議
手書きのポリライン座標を送受信
まずはサーバー側から
ハブクラス→サーバーAPIの端点。このクラスからAPIメソッドを公開。
SignalR
クライアントSignalRハブ“SharedWhiteBoardHub” ハブ上のメソッド群
“PlaceLine”
ハブクラスの実装
ハブクラス→サーバーAPIの端点。このクラスからAPIメソッドを公開。
Microsoft.AspNet.SignalR.HubクラスHubクラスを継承すると、自動的に認識される
外部から呼び出されるメソッドの定義
接続中の全てのクライアントの「DrawLine」メソッドにコールバック
送受信データの定義
文字列や数値が1~4個なら、直接引数に定義できます。
それ以上の複雑なデータをやり取りする場合は、エンティティクラスを定義して、このクラスごと送受信します。
エンティティクラスは、DataContract属性で修飾した、パブリックな値の入れ物とします。
最終的に、Json.NETによってJsonとの相互変換が行われる事に注意。
全く同じクラスをサービス側とクライアント側の両方で定義しても良いが、どうせならPortable Class Libraryにして共用しよう。
送受信データの定義
DataContract属性で修飾したクラス
DataMember属性で修飾したパブリックなプロパティ
必要なだけメンバを定義可能。Jsonで表現可能かどうかは考慮する必要がある。
クライアント側は?
クライアントから、ハブのメソッドを呼び出す
サーバーからのコールバックを受信する
“SharedWhiteBoardHub” PlaceLine()
DrawLine()
クライアントの実装 (NuGet導入)
まずはクライアントにNuGetでライブラリを導入 (2.0.2)“Install-Package Microsoft.AspNet.SignalR.Client”
あるいは、Portable Class Library版 (2.0.1)“Install-Package Microsoft.AspNet.SignalR.Client.Portable”(これは私が作って配布したものです。SL4/WP7.5にも対応、但し、WebSocket接続は出来ません)
パッケージ依存は多いので、図での説明は省略します (汗BCL, Json.NET, HttpClientなど
クライアントの実装 (ハブへの接続)
クライアントの動作を開始
HubConnectionクラスが、ハブへの接続を管理する
CreateHubProxyで、サーバーのハブクラスのプロキシ(代理)インスタンスを生成する。型はIHubProxyインターフェイス。
クライアントの実装 (ハブのメソッドを実行)
LineInformationクラス(エンティティ)に、送信する情報を代入
保存しておいたハブプロキシのInvokeメソッドを呼び出す。メソッド名:「PlaceLine」必要ならawaitする
クライアントの実装 (コールバック1)
コールバックするスレッドはワーカースレッドなので、UIを操作するにはUIスレッド(メインスレッド)へのマーシャリングが必要。
クライアントの実装 (コールバック2)
Start前に、コールバックメソッドを登録する。On<T>のT型が、受信する引数
デモ
上手く行かなかったら...
わかってるわネ?
Try it!
http://signalrbootcamp.cloudapp.net/WhiteBoard.html
IIS ExpressからAzureへ
SignalRはもちろん、Azure上で使えます。
WebSocketで接続OKです。
OS Family 3以降が必要(Windows Server 2012)
クライアント側が.NET4.5以上かつWindows 8以上
WireSharkでWebSocket
パケットを確認
Azure Tips
標準的な使用方法は、クラウドサービス(Webロール)
ワーカーロールでも使用可能。OWINのホストをワーカーロールで実行する(NuGetで、OWIN hostで検索すると、色々出てきます)。
Webサイトでも使用可。但し、WebSocketで接続する場合は、最大接続数の制限に注意。
Free: (5) concurrent connections per website instance
Shared: (35) concurrent connections per website instance
Standard: (350) concurrent connections per website instance
http://blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx
WebSocketは高速だけど...
WebSocketはHTTPで接続した際のTCPソケットを使用し続けます。→リソース消費としては大きい。
また、TCPとして接続が維持され続けるため、これを逆手にステートフル・セッションリッチなインターフェイスを考えてしまいます。
が、それではAzureの強みである「スケーラブルなインスタンスの拡張」が出来なくなってしまいます。
どうやって対処する?
スケーラビリティ1 VIPスワップでは切断されない
インスタンスを入れ替える場合に、VIPスワップを使うと、クライアント側のWebSocket接続(TCP接続)を維持したまま、インスタンスを入れ替える事が出来ます。
WebSocket接続(維持される)
VIPスワップここは切断される
WebSocketを認識する負荷分散ルーター DB(データ)
クライアント側の接続は維持されますが、サーバー側は当然維持されません。そのため、Azure内のWebSocketが切断され、かつクライアント側は接続が維持されているということを念頭に置く必要があります。
HTTPによるREST APIの置き換えシナリオであれば、初めからステートレスで設計している筈なので、この挙動に問題なくフィットします。(恐らく、必要なデータはバックエンドのDBに保存している筈)
WebSocketでの接続を念頭に置いていると、便利さゆえに、どこかでステートフルな設計にしてしまう可能性があるので、注意が必要です。
スケーラビリティ1 VIPスワップでは切断されない
複数のインスタンスが存在すると、インスタンスをまたがってクライアントとのメッセージ送受信を実行する必要があります。
スケーラビリティ2 インスタンス間通信
異なるインスタンスに接続している
どうやってメッセージを送受信する?DBを経由?
SignalRにインスタンス間通信の為の拡張インターフェイスがあります。Azure上では”Azure ServiceBus”が使えます。
スケーラビリティ2 インスタンス間通信
Azure ServiceBus
Azure ServiceBusは「Microsoft ASP.NET SignalR Service Bus Messaging Backplane」という名称でNuGetで公開されています。“Install-Package Microsoft.AspNet.SignalR.ServiceBus“http://www.asp.net/signalr/overview/signalr-20/performance-and-scaling/scaleout-with-windows-azure-service-bus
ServiceBusの実装は、あまりに多いクライアントにはフィットしないとの話があります。
他にも、SQL Serverを使うものや、OSSインメモリデータベースのRedisを使用した実装などがあります。
スケーラビリティ2 インスタンス間通信