センサーのデータを SignalR でホストする (2)

前回のセンサーのデータを SignalR でホストする (1) では、
センサーのデータをトラッキングするコンソール アプリケーションを作成しました。

今回は、そのデータをリアルタイムで配信するサービスを ASP.NET SignalR で作成してみたいと思います。
ただし IIS 上の Web サービスとしてホストするわけではなく、コンソール アプリケーションでホストします。
そのためには、ASP.NET SignalR Self Host を利用します。

 

(2) ASP.NET SignalR でサービスをセルフホストする

準備として、次のものを参照に追加する必要があります。

  • ASP.NET SignalR Self Host (Microsoft.AspNet.SignalR.SelfHost)
  • Microsoft.Owin.Cors

Visual Studio で、前回作成したプロジェクトを右クリックして [Nuget パッケージの管理] を選択します。
上記のパッケージを検索してインストールします。

ASP.NET SignalR Self Host

Microsoft.Owin.Cors

 

では、実装です。
IIS 上の ASP.NET SignalR と同様に、サービスを表すクラスを Hub クラスの具象クラスとして実装します。

まず、照度センサーに対する LightSensorHub クラスを実装します。


public class LightSensorHub : Hub
{
    static readonly IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<LightSensorHub>();
    static readonly LightSensor lightSensor = LightSensor.GetDefault();

    public static void StartBroadcast()
    {
        lightSensor.ReportInterval = 500;
        lightSensor.ReadingChanged += (o, e) =>
        {
            Console.WriteLine("Light: {0} lx", e.Reading.IlluminanceInLux);
            hubContext.Clients.All.NotifyIlluminanceInLux(e.Reading.IlluminanceInLux);
        };
    }

    public float GetIlluminanceInLux()
    {
        return lightSensor.GetCurrentReading().IlluminanceInLux;
    }
}


クライアント側から直接呼び出すためのメソッドとして、GetIlluminanceInLux メソッドを定義しています。
逆に、クライアント側にプッシュ送信するためには、LightSensorHub クラスに対する IHubContext オブジェクトを取得します。

クライアント側から呼び出されたときであれば Hub.Clients プロパティからプッシュ送信できるのですが、
任意のタイミングでクライアント側にデータをプッシュするにはこのようにします。

電子コンパスに対しても同様に、CompassHub クラスを実装します。


public class CompassHub : Hub
{
    static readonly IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<CompassHub>();
    static readonly Compass compass = Compass.GetDefault();

    public static void StartBroadcast()
    {
        compass.ReadingChanged += (o, e) =>
        {
            var rounded = Math.Round(e.Reading.HeadingMagneticNorth, 3);
            Console.WriteLine("Compass: {0} °", rounded);
            hubContext.Clients.All.NotifyHeadingMagneticNorth(rounded);
        };
    }

    public double GetHeadingMagneticNorth()
    {
        return Math.Round(compass.GetCurrentReading().HeadingMagneticNorth, 3);
    }
}


 

Web サーバーを起動するためのクラスとして、Startup クラスを実装します。
Configuration メソッドに、起動時の構成を記述します。


class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCors(CorsOptions.AllowAll);
        app.MapSignalR();

        LightSensorHub.StartBroadcast();
        CompassHub.StartBroadcast();
    }
}


IAppBuilder.UseCors メソッドにより、CORS (Cross-Origin Resource Sharing) の設定をします。
要するにクロスドメインのアクセス許可ですが、AllowAll を指定することですべてのドメインからのアクセスを許可します。

ホストする URL のパスは既定で /signalr ですが、これを明示的に指定するには、

app.MapSignalR("/signalr", new HubConfiguration());

のようにします。

 

最後に、Main メソッドを書き換えます。
ポートを指定して、Web サーバーを起動します。


class Program
{
    const string SelfHostUrl = "http://localhost:8080";

    static void Main(string[] args)
    {
        using (WebApp.Start(SelfHostUrl))
        {
            Console.WriteLine("Press [Enter] to exit.");
            Console.ReadLine();
        }
    }
}


 

このようにして、リアルタイム双方向サービスをセルフホストできるようになります。
次回はクライアントとなる HTML アプリを作成します。

つづく

前: センサーのデータを SignalR でホストする (1)
次: センサーのデータを SignalR でホストする (3)

作成したサンプル
WinRT-SignalR-Sample (GitHub) (今回までの分)
WinRT-SignalR-Sample (GitHub)

バージョン情報
.NET Framework 4.5
ASP.NET SignalR Self Host 2.0
Microsoft.Owin.Cors 2.0

参照
Tutorial: SignalR Self-Host

コメント / トラックバック2件 to “センサーのデータを SignalR でホストする (2)”

  1. センサーのデータを SignalR でホストする (3) | Do Design Space Says:

    […] 前回のセンサーのデータを SignalR でホストする (2) では、サービス側を実装しました。 今回はクライアント側となる Web アプリケーションを実装します。 […]

  2. センサーのデータを SignalR でホストする (1) | Do Design Space Says:

    […] 次: センサーのデータを SignalR でホストする (2) […]


コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。