C#でSignalRを使用した通信を行いたい その4(接続の有効期間イベント) | プログラミングがわからなすぎる

プログラミングがわからなすぎる

気が向いた時の備忘録。プログラミングは好きなのに物凄く単純なものしか理解できないからメモしていくうちに覚えられたらいいな
ターゲットフレームワークは大体4.7.2

クライアント側で切断を検知したいなって思ったときに

Microsoftのページに「接続の有効期間イベント」なるものが記載されていたので

これをサンプルに実装してみた

 

参考:ASP.NET SignalR Hubs API ガイド - .NET クライアント (C#)

 

 

ソースに追加してみた 

using Microsoft.AspNet.SignalR.Client;
using System;

namespace SignalRClientTest
{
    class SignalRClient
    {
        private static HubConnection hub;
        private static IHubProxy proxy;
        private const string URL = "http://localhost:8088";
        private const string HUB_CLASS = "TestHub";

        /// <summary>
        /// 接続処理
        /// </summary>
        /// <returns>結果 true:成功 false:失敗</returns>
        public static bool Connect()
        {
            try
            {
                hub = new HubConnection(URL);
                proxy = hub.CreateHubProxy(HUB_CLASS);

                hub.Received += (string str) => Console.WriteLine("データを受信しました。:" + str);
                hub.ConnectionSlow += () => Console.WriteLine(
                    "低速または頻繁に切断される状態です。");
                hub.Reconnecting += () => Console.WriteLine("再接続を開始しました。");
                hub.Reconnected += () => Console.WriteLine("再接続しました。");
                hub.StateChanged += (StateChange state) =>
                {
                    Console.WriteLine("状態が変更されました。");
                    Console.WriteLine(" 旧" + state.OldState);
                    Console.WriteLine(" 新" + state.NewState);
                };
                hub.Error += (Exception e) => Console.WriteLine(
                    "エラーが発生しました。:" + e.Message);
                hub.Closed += () => Console.WriteLine("接続が切断されました。");


                hub.Start().Wait(); // 接続実行
            }
            catch
            {
                // 接続失敗
                return false;
            }
            return true;
        }

        /// <summary>
        /// 切断処理
        /// </summary>
        public static void DisConnect()
        {
            hub?.Stop();
            hub?.Dispose();
        }
    }
}

受け取るイベントはそれぞれConsole.WriteLine()している内容

Received、StateChanged、Errorは引数を受け取らないとエラーが出たので受け取る

上記以外にもなにかあるのかもしれないけど分からないので気が向いたときに調べます

一番欲しいのはClosedだし…

イベント発生時に処理を複数行書きたい場合はStateChangedで書いているような形でいいみたい

 

実行結果 

エラーが発生しました。:内部 WebSocket エラーが発生しました。詳細については、innerException (存在する場合) を参照してください。★サーバを停止させた
状態が変更されました。
 旧Connected
 新Reconnecting
再接続を開始しました。
エラーが発生しました。:リモート サーバーに接続できません。
状態が変更されました。★サーバを開始させた
 旧Reconnecting
 新Connected
再接続しました。
状態が変更されました。
 旧Connected
 新Disconnected
接続が切断されました。★クライアントから接続を切断させた

コンソールの出力から挙動だけ抜き出した結果はこんな感じ

★青字の部分は実行時の操作です

接続中にサーバを停止させるとErrorが発生し、

StateChangedで変更された状態を受け取るみたい。

そのまま何度か接続リトライ

リトライ中にサーバが復帰したらそのままちゃんと再接続された。

クライアントから切断すると、Closedが走る。

 

結果は記載してはないけど、接続リトライのまま放置してたら

Errorを吐き続けて、そのうちリトライをあきらめてClosedになります。

 

今回ConnectionSlowとReceivedは検知できなかったけど

Receivedは恐らくサーバとクライアントでやりとりを行わないと検知できないかな?

ConnectionSlowは強制的に起こす方法はわかんない

※2024/02/10追記

サーバからクライアントメソッドを呼び出してみたらReceivedイベント発生してました

 

接続のイベント発生方法まとめ 

Received:サーバ側からクライアントのメソッドを呼び出す

ConnectionSlow:デバッグでゆっくりステップ実行してたら出てる

Reconnecting:サーバ側を停止→すぐ開始

Reconnected:サーバ側を停止→すぐ開始

StateChanged:サーバ側を停止→すぐ開始

Error:サーバ側を停止

Closed:クライアントから切断、またはサーバ側を停止して暫く待つ