signalrブートキャンプ

40
地理冗長の中心でAzure愛を叫ぶ in 名古屋 2014.3.1 Kouji Matsui (@kekyo2) SignalR ブートキャンプ SignalR ブートキャンプ

Upload: kouji-matsui

Post on 08-Jul-2015

796 views

Category:

Software


2 download

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/

TRANSCRIPT

Page 1: SignalRブートキャンプ

地理冗長の中心でAzure愛を叫ぶ in 名古屋 2014.3.1 Kouji Matsui (@kekyo2)

SignalR ブートキャンプSignalR ブートキャンプ

Page 2: SignalRブートキャンプ

自己紹介

Kouji Matsui (@kekyo2)

名古屋のコミュニティ、MiCoCiのメンバーです。

「なごやこわい」のメンバーではありませんw

アーキテクトやってます。あと、スクラム道もはじめました。

Page 3: SignalRブートキャンプ

リアルタイム通信、始まる

サーバーとクライアントを接続して、何か連携できることがしたいよね!! TCPとかでリアルタイム通信! ゲーム!!

でも、基本、クライアントの人だから、サーバーわかんないんだ、何もかも(遠い目)

「SignalR」ってライブラリを使えば、簡単にリアルタイム通信出来るよ!! サーバーの管理なんて、Windows Azureに任せちゃえばいい!

Page 4: SignalRブートキャンプ

SignalRが使えると?

SignalRおいしい? それ何?

TCPでソケット繋いでどうとか、通信電文がどうだとか、面倒な事は殆ど自動でやってくれる! → だから、本来実現したかったことに集中出来る!!

ほうほう、それで?

簡単実現!

Page 5: SignalRブートキャンプ

SignalRがやってくれる事

Jsonによる通信(プレーンではない)

通信手段の自動的な選択HTTPやWebSocketなど

サーバーのメソッドを呼び出す感覚でコードを書けるワ

Page 6: SignalRブートキャンプ

通信を抽象化

・同報通知も可能・特定端末にだけ送信・グルーピングして送信

Page 7: SignalRブートキャンプ

サポートする環境は?

Windows PC / IE / Chrome / etc...

Windows Phone / Tablets...Windows Server

Page 8: SignalRブートキャンプ

さぁ、はじめよう!

Page 9: SignalRブートキャンプ

SignalR使おうとしたら、OWINって?

Open Web Interface for .NET

ウェブサーバー向けの新しいフレームワーク

えぇー?またフレームワーク増えたの?!

まぁ、そうなんですが、ASP.NET WebFormやMVCとは位置づけがちょっと違います。SignalRはこれに乗っかります。

OWINの詳細は知らなくても大丈夫ですが、どんなものなのか、少しだけ紹介します。

大丈夫、NuGetを使えば簡単に導入できます!

Page 10: SignalRブートキャンプ

見せてもらう必要がありそうネ、全て取り払った 最小のコードとやらを

いくらNuGetで簡単にライブラリを導入できても、一度にあまりに大量のコードが追加されると、何が何だか... orz

では、「スクラッチ」に近い状態でのコードをお見せします。

Page 11: SignalRブートキャンプ

論よりOWIN

OWINの導入は超簡単。NuGet一発!”Install-Package Microsoft.Owin.Host.SystemWeb” (2.0.2)

Owin Microsoft.Owin

Microsoft.Owin.Host.SystemWeb

ASP.NETでOWINを動作可能にする

似たようなパッケージが沢山公開されているので、注意!

Page 12: SignalRブートキャンプ

論よりOWIN

「OWINスタートアップクラス」を追加

スタートアップクラスとOwinを結びつける

Page 13: SignalRブートキャンプ

Hello! OWIN

IOwinContext – HttpContextの抽象インターフェイス

Page 14: SignalRブートキャンプ

何がどうなってる?

ASP.NETウェブフォームでは、HttpContextを受け取るまでに、System.Web.UI.Pageからページを生成する必要がありました。

Pageクラスはデカい、ページレンダリングの余分なコードが多い。シンプルではない。例のように、Hello World的コードであっても、非常に大がかりな仕掛けが動作します。

OWINは非常にシンプル。IOwinContextを受け取って動作するまでに必要な、複雑なフレームワーク構造は存在しません。

Page 15: SignalRブートキャンプ

IOwinContext

Page 16: SignalRブートキャンプ

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

Page 17: SignalRブートキャンプ

Web.configがおかしい...

2.0.2をNuGetで導入時に、Web.configに不正なエントリーが追加されるので、手動で修正が必要。

アセンブリバージョンの3番目要素を広くする。この例では「99」に設定した

Page 18: SignalRブートキャンプ

OWINでSignalRのセットアップ

OWINスタートアップクラスで、SignalRにコンテキストを転送する

Microsoft.AspNet.SignalR.Core.dll

Owin.OwinExtensions.MapSignalR()

コンテキストパイプラインをSignalRに転送

Page 19: SignalRブートキャンプ

準備完了

後はハブとメソッドを決めるだけネ?

Page 20: SignalRブートキャンプ

何を作る?

ホワイトボードアプリ

Windows Phone・Silverlight・WPFでリアルタイム白板会議

手書きのポリライン座標を送受信

Page 21: SignalRブートキャンプ

まずはサーバー側から

ハブクラス→サーバーAPIの端点。このクラスからAPIメソッドを公開。

SignalR

クライアントSignalRハブ“SharedWhiteBoardHub” ハブ上のメソッド群

“PlaceLine”

Page 22: SignalRブートキャンプ

ハブクラスの実装

ハブクラス→サーバーAPIの端点。このクラスからAPIメソッドを公開。

Microsoft.AspNet.SignalR.HubクラスHubクラスを継承すると、自動的に認識される

外部から呼び出されるメソッドの定義

接続中の全てのクライアントの「DrawLine」メソッドにコールバック

Page 23: SignalRブートキャンプ

送受信データの定義

文字列や数値が1~4個なら、直接引数に定義できます。

それ以上の複雑なデータをやり取りする場合は、エンティティクラスを定義して、このクラスごと送受信します。

エンティティクラスは、DataContract属性で修飾した、パブリックな値の入れ物とします。

最終的に、Json.NETによってJsonとの相互変換が行われる事に注意。

全く同じクラスをサービス側とクライアント側の両方で定義しても良いが、どうせならPortable Class Libraryにして共用しよう。

Page 24: SignalRブートキャンプ

送受信データの定義

DataContract属性で修飾したクラス

DataMember属性で修飾したパブリックなプロパティ

必要なだけメンバを定義可能。Jsonで表現可能かどうかは考慮する必要がある。

Page 25: SignalRブートキャンプ

クライアント側は?

クライアントから、ハブのメソッドを呼び出す

サーバーからのコールバックを受信する

“SharedWhiteBoardHub” PlaceLine()

DrawLine()

Page 26: SignalRブートキャンプ

クライアントの実装 (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など

Page 27: SignalRブートキャンプ

クライアントの実装 (ハブへの接続)

クライアントの動作を開始

HubConnectionクラスが、ハブへの接続を管理する

CreateHubProxyで、サーバーのハブクラスのプロキシ(代理)インスタンスを生成する。型はIHubProxyインターフェイス。

Page 28: SignalRブートキャンプ

クライアントの実装 (ハブのメソッドを実行)

LineInformationクラス(エンティティ)に、送信する情報を代入

保存しておいたハブプロキシのInvokeメソッドを呼び出す。メソッド名:「PlaceLine」必要ならawaitする

Page 29: SignalRブートキャンプ

クライアントの実装 (コールバック1)

コールバックするスレッドはワーカースレッドなので、UIを操作するにはUIスレッド(メインスレッド)へのマーシャリングが必要。

Page 30: SignalRブートキャンプ

クライアントの実装 (コールバック2)

Start前に、コールバックメソッドを登録する。On<T>のT型が、受信する引数

Page 31: SignalRブートキャンプ

デモ

上手く行かなかったら...

わかってるわネ?

Try it!

http://signalrbootcamp.cloudapp.net/WhiteBoard.html

Page 32: SignalRブートキャンプ

IIS ExpressからAzureへ

SignalRはもちろん、Azure上で使えます。

WebSocketで接続OKです。

OS Family 3以降が必要(Windows Server 2012)

クライアント側が.NET4.5以上かつWindows 8以上

WireSharkでWebSocket

パケットを確認

Page 33: SignalRブートキャンプ

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

Page 34: SignalRブートキャンプ

WebSocketは高速だけど...

WebSocketはHTTPで接続した際のTCPソケットを使用し続けます。→リソース消費としては大きい。

また、TCPとして接続が維持され続けるため、これを逆手にステートフル・セッションリッチなインターフェイスを考えてしまいます。

が、それではAzureの強みである「スケーラブルなインスタンスの拡張」が出来なくなってしまいます。

どうやって対処する?

Page 35: SignalRブートキャンプ

スケーラビリティ1 VIPスワップでは切断されない

インスタンスを入れ替える場合に、VIPスワップを使うと、クライアント側のWebSocket接続(TCP接続)を維持したまま、インスタンスを入れ替える事が出来ます。

WebSocket接続(維持される)

VIPスワップここは切断される

WebSocketを認識する負荷分散ルーター DB(データ)

Page 36: SignalRブートキャンプ

クライアント側の接続は維持されますが、サーバー側は当然維持されません。そのため、Azure内のWebSocketが切断され、かつクライアント側は接続が維持されているということを念頭に置く必要があります。

HTTPによるREST APIの置き換えシナリオであれば、初めからステートレスで設計している筈なので、この挙動に問題なくフィットします。(恐らく、必要なデータはバックエンドのDBに保存している筈)

WebSocketでの接続を念頭に置いていると、便利さゆえに、どこかでステートフルな設計にしてしまう可能性があるので、注意が必要です。

スケーラビリティ1 VIPスワップでは切断されない

Page 37: SignalRブートキャンプ

複数のインスタンスが存在すると、インスタンスをまたがってクライアントとのメッセージ送受信を実行する必要があります。

スケーラビリティ2 インスタンス間通信

異なるインスタンスに接続している

どうやってメッセージを送受信する?DBを経由?

Page 38: SignalRブートキャンプ

SignalRにインスタンス間通信の為の拡張インターフェイスがあります。Azure上では”Azure ServiceBus”が使えます。

スケーラビリティ2 インスタンス間通信

Azure ServiceBus

Page 39: SignalRブートキャンプ

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 インスタンス間通信

Page 40: SignalRブートキャンプ

Cheers!

本日のスライド・サンプルコードは、後日ブログに掲載します。

kekyoの丼http://kekyo.wordpress.com