10

私たちは興味深い問題に遭遇しています。セットアップは次のようになります。

  • Windows Server2012上のSignalRServer(ASP.NET MVCアプリケーション)。
  • 同じサーバー(Windows Server 2012)上のSencha HTML5アプリ(SignalRクライアント)。
  • Windows Server2008R2サーバー上の.NETWindowsサービス。これは、SignalRクライアントとしても機能します。

最初はSignalR0.5.3を使用していましたが、WindowsサービスのSignalRサーバーへの接続が切断されていることを確認し始めました。この頻度は、数分ごとから数時間ごとの範囲です。ほとんどの場合、再接続しますが、ときどき再接続に失敗するため、Windowsサービスは数日に1回接続を失います。しかし、それに決まったパターンはありません。サーバーの再起動/バックアップなどとは関係ありません。Windowsサービスにログを追加して、クライアント接続のStateChangedイベントを監視し、切断して再接続するとイベントが発生するが、再接続しない場合は発生しないことを確認しました。

次に、このスレッドに出くわしました。クライアントは常に再接続しています

そして、すべてをSignalR 1.0.1にアップグレードすることにしました(とにかくある時点でアップグレードする必要がありました)。Windowsサービスもフレームワーク4.5(Framework 2.0から)にアップグレードされ、新しいMicrosoft.AspNet.SignalR.Client.dllを参照するようになりました。これにより、(新しく追加された接続プロパティを使用して)Windowsサービスが実際にServerSentEventsプロトコルを使用していたことを確認することもできました。同じWindowsサービスをWindowsServer2012マシンにインストールするには、WebSocketプロトコルを使用します。これはこのスレッドと一致しています。SignalR.NETクライアントはWindows7でWebSocketをサポートしていません

ただし、Windows Server2008R2サーバーでのサービスの動作は変更されていません。それでも切断して再接続し、時々接続を失います。いくつかの制限により、WindowsサービスにWindows Server 2012を使用できず、古いOSでスタックしています。これは、websocketプロトコルを使用するWindowsサービスがすべての問題を解決するということではありません(徹底的にテストしていません)。

3番目に試したのは、GitHubからソースコードを取得してコンパイルし、サービス(SignalRサーバーとクライアント)をアップグレードすることです。これは、潜在的なバグ修正を含む最新のコピーを確実に取得するために行われました。

しかし、それは役に立ちませんでした。私たちは今、私たちの選択肢を使い果たしたと感じているところにいます。提案をいただければ幸いです。ありがとう。

=====================================

編集:詳細:

さて、これでもう少し情報があります。Windowsサービス(SignalRクライアント)にコードを追加して、30分ごとにSignalRサーバーにログインします(接続のテスト用)。

30分ごとにクライアント側で発生することは次のとおりです。

WriteEvent(Now(), "INFO", "PING", "Performing logon procedure with SiteCode = " & msSiteCode & ".")
trans.Invoke("login", New String() {msSiteCode, "", "SERVER", "", ""})

ここで、transはHubから継承するサーバー側クラスのインスタンスであり、WriteEventは基本的にログファイルに書き込むためのトレースです。

また、クライアント側には次のような「isLoggedIn」メソッドもあります。

Private Sub isLoggedIn(ByVal bLoggedIn As String)
        If bLoggedIn Then
            WriteEvent(Now(), "INFO", "", "SignalR Server: Authenticated")           
        Else
            WriteEvent(Now(), "ERROR", "", "SignalR Server: Authentication failed")
        End If
End Sub

サーバー側には、ログイン方法があります。

Public Sub login(ByVal sAccount As String, _
                     ByVal sCompanyCode As String, _
                     ByVal sClientId As String, _
                     ByVal sPassword As String, _
                     ByVal sModuleCode As String)
       Try
            'Some code omitted that validates the user and sets bValidated.

            If bValidated Then
                'Update user in cache
                ConnectionCache.Instance.UpdateCache(userId, Context.ConnectionId, UserCredential.Connection_Status.Connected)
                Clients.Caller.isLoggedIn(True)

                Dim connectionId As String = ConnectionCache.Instance.FindConnectionId(userId)
                LogEvent("Successful login for connectionid: " & connectionId & ". Context. User: " & userId, _
                         EventLogEntryType.Information)
            Else
                Clients.Caller.isLoggedIn(False, results)
            End If
        Catch ex As Exception
            LogEvent("Login: " & ex.Message, EventLogEntryType.Error)
        End Try
End Sub

クライアントログファイルを見ると、30分ごとに次のログエントリが取得されます。

  • SiteCode=ABCDを使用してログオン手順を実行します。
  • SignalRサーバー:認証済み

したがって、loginサーバー側メソッドが呼び出されており、isLoggedInクライアント側メソッドも呼び出されていることがわかります。

ただし、ある時点で、サーバー側のメソッドが呼び出されている間、isLoggedInクライアント側のメソッドは呼び出されません。したがって、30分ごとに、1つのエントリのみを取得し始めます。

  • SiteCode=ABCDを使用してログオン手順を実行します。

さらに、ログイベント:

LogEvent("Successful login for connectionid: " & connectionId & ". Context. User: " & userId, EventLogEntryType.Information)

サーバー側のログイン方法では、サーバー側のログに書き込まれます。したがって、Clients.Caller.isLoggedIn(True)は期待どおりに呼び出されますが、クライアント側では表示されません。

つまり、クライアントは常にサーバーにアクセスでき、サーバー側(login)関数を呼び出すことができますが、サーバーはクライアント側(isLoggedIn)関数の呼び出しに失敗し、これは次の場所で発生し始めます。いくつかのポイント。

また、これは.NETクライアントに固有のものである可能性があります。これは、HTML5/javascriptクライアントでこれが発生するのを見たことがないと確信しているためです。

4

1 に答える 1

4

最後に、単純な「PINGING」関数を作成しました。これは 15 分ごとに呼び出されます。ロジックは次のとおりです。

  1. SignalR クライアントには、サーバーの PING メソッドを 15 分ごとに呼び出すタイマーがあります。
  2. サーバーは、応答として、クライアント上でクライアントの PINGCLIENT メソッドを呼び出します。
  3. クライアントの次の PING タイマー イベント (15 分後) で、応答があるかどうかを確認します。そうでない場合は、すべてのアクティビティを一時停止し、ハブ接続を再初期化します。次に、PINGING タイマーを再起動します。

そのため、原因を特定することをあきらめましたが、「サーバーからクライアントへ」の接続が失われた場合に対処するための回避策があります。これは、signalR の組み込みの再接続ロジックに追加されることに注意してください。

ログも保持しており、これは平均して 1 日に 1 回発生します (クライアントはサーバーから PING を返されません)。

于 2014-04-29T22:49:07.980 に答える