90

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

SignalR は時々魔法のように自動再接続するため、機能または構成設定が不足しているのではないかと考えています。

自動的に再接続するクライアントをセットアップする最良の方法は何ですか?


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

SignalR 接続の有効期間に関するドキュメントといくつかの記事を読みましたが、クライアントの再接続を処理する方法についてはまだ不明です。

4

5 に答える 5

73

私はついにこれを理解しました。この質問を始めてから学んだことは次のとおりです。

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

アプリが SignalR サーバーにすばやく再接続する必要がありましたが、接続が自動的に再接続されない、または再接続に正確に 30 秒かかる (基になるプロトコルのタイムアウトが原因で) という問題が引き続き発生しました。

最終的にテストしたシナリオは 3 つあります。

シナリオ A - アプリが初めて読み込まれたときに接続します。これは初日から問題なく機能しました。3G モバイル接続でも 0.25 秒未満で接続が完了します。(ラジオがすでにオンになっていると仮定します)

シナリオ B - アプリが 30 秒間アイドル状態または閉じられた後、SignalR サーバーに再接続します。このシナリオでは、SignalR クライアントは最終的に、特別な作業を行わなくても独自にサーバーに再接続しますが、再接続を試行する前に正確に 30 秒待機するようです。(私たちのアプリには遅すぎます)

この 30 秒間の待機期間中に、HubConnection.Start() を呼び出してみましたが、効果はありませんでした。HubConnection.Stop() の呼び出しにも 30 秒かかります。関連するバグが SignalR サイトで見つかりましたが、解決済みと思われますが、v2.0.3 でも同じ問題が発生しています。

シナリオ C - アプリが 120 秒以上アイドル状態または閉じられた後、SignalR サーバーに再接続します。このシナリオでは、SignalR トランスポート プロトコルが既にタイムアウトしているため、クライアントが自動的に再接続することはありません。これは、クライアントが常に再接続するわけではありませんが、ときどき自動的に再接続する理由を説明しています。幸いなことに、HubConnection.Start() の呼び出しは、シナリオ A のようにほぼ瞬時に機能します。

そのため、アプリを 30 秒間閉じていた場合と 120 秒以上閉じていた場合では、再接続の条件が異なることに気付くのに少し時間がかかりました。また、SignalR のトレース ログは、基になるプロトコルで何が起こっているかを明らかにしていますが、トランスポート レベルのイベントをコードで処理する方法はないと思います。(Closed() イベントは、シナリオ B では 30 秒後に発生し、シナリオ C では即座に発生します。これらの再接続待機期間中、State プロパティは「接続済み」と表示されます。他の関連するイベントやメソッドは発生しません)

解決策: 解決策は明らかです。SignalR が再接続の魔法を実行するのを待っているわけではありません。代わりに、アプリがアクティブ化されたとき、または電話のネットワーク接続が復元されたときに、単にイベントをクリーンアップし、HubConnection を逆参照しています (30 秒かかるため破棄できません。できればガベージ コレクションが処理してくれることを願っています)。 )、新しいインスタンスを作成します。今、すべてがうまくいっています。何らかの理由で、単に新しいインスタンスを作成するのではなく、永続化された接続を再利用して再接続する必要があると考えました。

于 2014-05-13T23:59:05.623 に答える
47

切断されたイベントにタイマーを設定して自動的に再接続を試みることは、私が知っている唯一の方法です。

JavaScript では、次のように行われます。

$.connection.hub.disconnected(function() {
   setTimeout(function() {
       $.connection.hub.start();
   }, 5000); // Restart connection after 5 seconds.
});

これは、ドキュメントで推奨されるアプローチです。

http://www.asp.net/signalr/overview/signalr-20/hubs-api/handling-connection-lifetime-events#clientdisconnect

于 2014-05-01T11:56:13.423 に答える
-2

魔法の再接続の問題を防ぐために、再接続状態が開始する前に、Android からサーバー メソッドを呼び出そうとする場合があります。

SignalR ハブ C#

 public class MyHub : Hub
    {
        public void Ping()
        {
            //ping for android long polling
        }
 }

アンドロイドで

private final int PING_INTERVAL = 10 * 1000;

private boolean isConnected = false;
private HubConnection connection;
private ClientTransport transport;
private HubProxy hubProxy;

private Handler handler = new Handler();
private Runnable ping = new Runnable() {
    @Override
    public void run() {
        if (isConnected) {
            hubProxy.invoke("ping");
            handler.postDelayed(ping, PING_INTERVAL);
        }
    }
};

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    System.setProperty("http.keepAlive", "false");

    .....
    .....

    connection.connected(new Runnable() {
        @Override
        public void run() {
            System.out.println("Connected");
            handler.postDelayed(ping, PING_INTERVAL);
    });
}
于 2015-01-24T23:18:09.920 に答える