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

前回のセンサーのデータを SignalR でホストする (3) では、
ASP.NET SignalR サービスに対するクライアントを HTML で実装しました。
今回は同様のクライアントをコンソール アプリケーションで実装します。

 

(4) コンソール アプリケーションからサービスにアクセスする

まず、[新しいプロジェクトの追加] でコンソール アプリケーション プロジェクトを作成します。

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

  • ASP.NET SignalR .NET Client (Microsoft.AspNet.SignalR.Client)

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

ASP.NET SignalR .NET Client

 

Program.cs を、次のように実装します。


class Program
{
    static void Main(string[] args)
    {
        Task.Run(() => StartConnection());

        Console.WriteLine("Press [Enter] to exit.");
        Console.ReadLine();
    }

    async static void StartConnection()
    {
        var connection = new HubConnection("http://localhost:8080/");
        connection.ConnectionSlow += () => Console.WriteLine("Connection is slow.");
        connection.Error += ex => Console.WriteLine(ex);

        var lightSensor = connection.CreateHubProxy("LightSensorHub");
        lightSensor.On<float>("NotifyIlluminanceInLux", NotifyIlluminanceInLux);
        var compass = connection.CreateHubProxy("CompassHub");
        compass.On<double>("NotifyHeadingMagneticNorth", NotifyHeadingMagneticNorth);

        await connection.Start();

        var illuminanceInLux = await lightSensor.Invoke<float>("GetIlluminanceInLux");
        NotifyIlluminanceInLux(illuminanceInLux);
        var headingMagneticNorth = await compass.Invoke<double>("GetHeadingMagneticNorth");
        NotifyHeadingMagneticNorth(headingMagneticNorth);
    }

    static void NotifyIlluminanceInLux(float illuminanceInLux)
    {
        Console.WriteLine("Light: {0} lx", illuminanceInLux);
    }

    static void NotifyHeadingMagneticNorth(double headingMagneticNorth)
    {
        Console.WriteLine("Compass: {0} °", headingMagneticNorth);
    }
}


HubConnection.CreateHubProxy メソッドで、Hub のプロキシを作成します。

サービス側から直接呼び出せるメソッドを定義するには、On メソッドを使います。
逆に、サービス側で定義されたメソッドを呼び出すには、Invoke メソッドを使います。

なお、サービスのパスを明示的に指定するには、

var connection = new HubConnection("http://localhost:8080/signalr", false);

のようにします。

 

では、これを実行します。
端末に手をかざしたり端末を回転したりすれば、サービス側からそれぞれのデータがプッシュ送信されます。

SensorsConsole

 

次回は、サービス側のアプリケーションを通知領域に常駐させるように変更します。

つづく

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

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

バージョン情報
.NET Framework 4.5
ASP.NET SignalR .NET Client 2.0

参照
Hubs API Guide – .NET Client (C#)

広告

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

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

 

(3) ブラウザーからサービスにアクセスする

まず、[新しいプロジェクトの追加] で [ASP.NET 空の Web アプリケーション] を選択し、
Web アプリケーション プロジェクトを作成します。

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

  • jQuery
  • ASP.NET SignalR JavaScript Client (Microsoft.AspNet.SignalR.JS)

通常、Web アプリケーション プロジェクトで ASP.NET SignalR のクライアント側もサービス側も実装する場合は
ASP.NET SignalR (Microsoft.AspNet.SignalR) をインストールしますが、
今回はクライアント側のみを利用するため、ASP.NET SignalR JavaScript Client をインストールします。

また、現在のところ、ASP.NET SignalR JavaScript Client をインストールすると、
古いバージョンである jQuery 1.6.4 が同時に入ってしまうため、先に jQuery を個別にインストールしておきます。

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

jQuery

ASP.NET SignalR JavaScript Client

 

プロジェクトに [HTML ページ] を追加し、名前を index.html とします。
index.html を次のように実装して、サービスからセンサーのデータを取得します。


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Sensors Client</title>
    <script src="Scripts/jquery-2.0.3.min.js"></script>
    <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
    <script src="http://localhost:8080/signalr/hubs"></script>
</head>
<body>
    <script type="text/javascript">
        $(function () {
            $.connection.hub.url = "http://localhost:8080/signalr";
            var appModel = { light: 0, compass: 0 };

            var lightSensor = $.connection.lightSensorHub;
            lightSensor.client.notifyIlluminanceInLux = function (illuminanceInLux) {
                appModel.light = illuminanceInLux;
                console.log("Light: %f lx", appModel.light);
            };
            var compass = $.connection.compassHub;
            compass.client.notifyHeadingMagneticNorth = function (headingMagneticNorth) {
                appModel.compass = headingMagneticNorth;
                console.log("Compass: %f °", appModel.compass);
            };

            $.connection.hub.start()
                .done(function () {
                    lightSensor.server.getIlluminanceInLux()
                        .done(lightSensor.client.notifyIlluminanceInLux);
                    compass.server.getHeadingMagneticNorth()
                        .done(compass.client.notifyHeadingMagneticNorth);
                });
        });
    </script>
</body>
</html>


サービス側から直接呼び出せるメソッドを定義するには、lightSensor.client.notifyIlluminanceInLux のように、
hub の client プロパティに関数を設定します。

逆に、サービス側で定義されたメソッドを呼び出すには、lightSensor.server.getIlluminanceInLux のように、
hub の server プロパティを経由して呼び出します。

これを実行します。
端末に手をかざしたり端末を回転したりすれば、サービス側からそれぞれのデータがプッシュ送信され、
ブラウザーのコンソールに値がレポートされます。

Sensors Client (コンソール)

 

あとは、GUI を追加すれば変化が視覚的にわかりやすくなります。
この先のコードは index.html (GitHub) をご覧ください。

Sensors Client 1

Sensors Client 2

 

次回は、コンソール アプリケーションでクライアントを作成します。

つづく

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

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

バージョン情報
.NET Framework 4.5
jQuery 2.0
ASP.NET SignalR JavaScript Client 2.0

参照
Tutorial: SignalR Self-Host

センサーのデータを 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