shuhelohelo’s blog

Xamarin.Forms多めです.

SignalRの自動再接続をもう少しくわしく.

環境

自動再接続を有効にする

SignalRの自動再接続を有効にするには,HubConnectionBuilderのインスタンス生成でwithAutomaticReconnect()を追加するだけ.

Javascriptの例:

www.jerriepelser.com

            var connection = new signalR.HubConnectionBuilder()
                .withUrl('/chathub') //startupのMapHubで指定したHubのURLを指定する.
                .withAutomaticReconnect()//自動再接続
                .build();

再接続の試行は所定の時間間隔で行われ,指定もできるがデフォルトでは切断されてから2秒,10秒,30秒経過のタイミングで再接続が行われる.

このタイミングは明示的に指定することもできて,その場合は以下のように配列を使ってミリ秒で指定する.

withAutomaticReconnect([2000, 100000, 300000])//デフォルトと一緒の設定

C#の例:

            connection = new HubConnectionBuilder()
                .WithUrl("https://localhost:44350/chathub")//アプリケーションからの接続の場合はフルで書く
                .WithAutomaticReconnect()
                .Build();

これも同じくデフォルトでは2秒,10秒,30秒経過のタイミングで再接続.

間隔を指定するには以下のようにTimeSpanの配列をWithAutomaticReconnectメソッドにわたす.

            connection = new HubConnectionBuilder()
                .WithUrl("https://localhost:44350/chathub")//アプリケーションからの接続の場合はフルで書く
                .WithAutomaticReconnect(new[] { TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30) })
                .Build();

再接続のカスタマイズ

指定した配列の分だけ再接続が行われると,以後は再接続が行われない.

それでよい場合はあるが,回数の制限なく再接続を試みたいときもある.

その場合は以下のように設定する.

Javascriptの場合:

            const connection = new signalR.HubConnectionBuilder()
                .withUrl('/chathub')
                .withAutomaticReconnect({
                    nextRetryDelayInMilliseconds: retryContext => {
                        return Math.random() * 10000; //0~10秒のランダムな間隔で再接続を試行.
                    }
                })
                .build();

C#の場合:

            IRetryPolicy retryPolicy = new RandomRetryPolicy();

            connection = new HubConnectionBuilder()
                .WithUrl("https://localhost:44350/chathub")
                .WithAutomaticReconnect(retryPolicy)
                .Build();
    public class RandomRetryPolicy : IRetryPolicy
    {
        private readonly Random _random = new Random();

        public TimeSpan? NextRetryDelay(RetryContext retryContext)
        {
            //2~5秒の間でランダムに再接続を試みる
            return TimeSpan.FromSeconds(_random.Next(2,5));
        }
    }

再接続の間隔はランダムに設定するとよい. これは複数のクライアントから同じタイミングでリクエストが送られることによるサーバー側の負荷を軽減するため.