xin9le.net

Microsoft の製品/技術が大好きな Microsoft MVP な管理人の技術ブログです。

SignalRのコネクション切断時に自動再接続する

リアルタイムな双方向通信を容易に実現させてくれる SignalR。その特性上、常時サーバー側とクライアント側のコネクションを張っています。定期的に ping を飛ばし合って死活監視を行い、長時間接続状態を確認できなければコネクションは切断されたものとみなして振る舞います。短時間であれば再度自動的に接続状態に入ります。このように、SignalR は接続の管理をほぼ自動で行ってくれて大変便利です。

ネットワーク接続が意図せず切れてしまうようなシチュエーションは、例えば以下のようなものが考えられます。

  • Wi-Fi 接続中に移動し、通信可能範囲から出た
  • 電車に乗っていてトンネルに入った
  • 誰かがハブに刺さっている LAN ケーブルを誤って抜いた

しかし、場合によってはそんなこんなな状況でも継続的に接続を確立し続けなければならないアプリケーション要件もあるでしょう。今回はそんな切断検知後の継続的な自動再接続の実装メモ。

for .NET Client

.NET Client ライブラリにおける切断検知は Closed イベントで行えます。以下はそのサンプルです。

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

connection.Closed += () =>
{
    await Task.Delay(5000);  //--- 5秒後にリトライ
    try
    {
        await connection.Start();
    }
    catch
    {
        //--- 再接続失敗
    }                
};

try
{
    await connection.Start();
}
catch
{
    //--- 接続失敗
}

ここでは切断後 5 秒待ってから再接続を試みるようにしています。重要なポイントは、Start メソッドで接続を試行した場合、たとえ一度も接続状態に入らなくても切断検知時には必ず Closed イベントが呼び出されるという点です。おかげで数秒遅延を入れるだけで継続的な接続を実装できます。

for JavaScript

JavaScript も考え方は同様です。切断イベント名やリトライ時の遅延の入れ方に違いがある点だけ気を付けましょう。

var connection = $.hubConnection();

connection.disconnected(function()
{
    setTimeout(function()
    {
        connection.start();
    }, 5000);
});

connection.start();