1. ホーム
  2. c#

[解決済み] SignalR 2.0 .NETクライアントとサーバーハブを再接続するためのベストプラクティス

2023-03-30 10:16:12

質問

モバイルアプリケーションでSignalR 2.0と.NETクライアントを使用していますが、さまざまな種類の切断を処理する必要があります。SignalRクライアントが自動的に再接続されることもあれば、次のように直接再接続しなければならないこともあります。 HubConnection.Start() を呼び出して直接再接続する必要がある場合もあります。

SignalRは魔法のように自動で再接続することがあるので、機能または設定を見逃しているのでは?

自動的に再接続するクライアントを設定する最善の方法は何ですか?


を処理する javascript の例を見たことがあります。 Closed() イベントを処理し、n秒後に接続するJavaScriptの例を見ました。何か推奨されるアプローチはありますか?

私は のドキュメントを読みました。 やSignalRの接続の寿命に関するいくつかの記事を読みましたが、クライアントの再接続をどのように処理するのかがまだ不明です。

どのように解決するのですか?

私は最終的にこれを理解しました。この質問を始めてから、私が学んだことは以下の通りです。

背景です。 Xamarin / Monotouchと.NET SignalR 2.0.3クライアントを使用してiOSアプリを構築しています。私たちは、デフォルトの SignalR プロトコルを使用しています - そして、それは Web ソケットの代わりに SSE を使用しているようです。Xamarin / MonotouchでWebソケットを使用することが可能かどうかは、まだわかりません。すべてはAzureのウェブサイトを使用してホストされています。

私たちは、アプリが SignalR サーバーにすばやく再接続する必要がありましたが、接続が勝手に再接続されない、または再接続にちょうど 30 秒かかる (基本的なプロトコルのタイムアウトによる) 問題が発生し続けました。

最終的に、3 つのシナリオをテストしました。

シナリオ A - アプリが最初にロードされたときに接続する。 これは初日から完璧に機能しました。接続は、3G モバイル接続でも 0.25 秒未満で完了します。(ラジオがすでにオンになっていると仮定して)

シナリオB - アプリが30秒間アイドル/クローズした後にSignalRサーバーに再接続する。 このシナリオでは、SignalR クライアントは特別な作業をしなくても、最終的に勝手にサーバーに再接続しますが、再接続を試みる前にちょうど 30 秒間待つようです。(私たちのアプリでは遅すぎます)。

この 30 秒の待機期間中に、HubConnection.Start() を呼び出してみましたが、何の効果もありませんでした。また、HubConnection.Stop() を呼び出しても、30 秒かかります。私は以下を見つけました。 に関連するバグがありましたが、これは解決されたようです。 を見つけましたが、v2.0.3でもまだ同じ問題があります。

シナリオ C - アプリが 120 秒以上アイドル/クローズされた後に SignalR サーバーに再接続する。

このシナリオでは、SignalR トランスポート プロトコルがすでにタイムアウトしているため、クライアントが自動的に再接続されることはありません。これは、クライアントが時々、しかし常に自分自身で再接続するわけではない理由を説明しています。良いニュースは、HubConnection.Start()を呼び出すと、シナリオAのようにほとんど即座に動作することです。

そのため、アプリが 30 秒間閉じているか、120 秒以上閉じているかによって、再接続の条件が異なることに気づくのにしばらくかかりました。また、SignalR のトレース ログは、基礎となるプロトコルで何が起こっているかを明らかにしますが、コードでトランスポート レベルのイベントを処理する方法があるとは思えません。(シナリオ B では 30 秒後に Closed() イベントが発生し、シナリオ C では即座に発生します。) これらの再接続待機期間中、State プロパティは "Connected" と表示します。

解決策 解決策は明らかです。SignalR が再接続の魔法をかけるのを待つのではありません。その代わりに、アプリが起動したとき、または電話のネットワーク接続が回復したときに、単にイベントをクリーンアップして HubConnection の参照を解除し(30 秒かかるので廃棄できませんが、ガベージ コレクションがそれを処理することを願っています)、新しいインスタンスを作成するのです。これで、すべてがうまくいくようになりました。なぜか、新しいインスタンスを作成するだけでなく、永続化された接続を再利用して再接続するべきだと思ったのです。