SignalR 不自动重新连接

Kyr*_*yro 5 signalr xamarin signalr.client

我有一个 SignalR Hub 和一个 .net Xamarin Android 客户端。当使用稳定的互联网连接时,它们工作正常,客户端可以发送到集线器,集线器可以发送到客户端。

但是,由于以下问题,客户端似乎无法自动重新连接(与在线文档所说的相反)并且尝试自己重新连接是不可能的。

如果客户端成功启动 HubConnection,状态将从 Disconnected -> Connecting -> Connected 变为 Disconnected -> Connecting -> Connected。但是,如果你从客户端拉网线所以没有办法为它获取到服务器。状态永远不会(我的意思是永远不会)从“已连接”改变。

我确实收到了一个“ConnectionSlow”事件,但是连接状态永远不会改变,并且在连接上调用 Start 没有任何作用,因为查看 signalR 源代码,它在内部检查 State !=“Connected”,如果不是,它只是返回。SignalR Github 源代码

我的问题是,你的意思是如何建立到服务器的 SignalR 连接并让它(或实现)自动重新连接。因为我尝试过的一切都不起作用。

xle*_*eon 1

I\xc2\xb4m 不太确定这是否对您有帮助,但请注意:

\n\n
    \n
  1. 在信号器断开连接(即:网络断开)后,我发现\xc2\xb4s更好地创建一个新的连接集线器。不要\xc2\xb4t期望信号器总是重新连接(它会尝试几秒钟,然后再见连接)。

  2. \n
  3. 如果您想解除当前连接,请不要尝试关闭它(signalR 在实际释放连接之前可能会冻结大约 20 秒。只需将连接变量重新分配为新的即可。

  4. \n
\n\n

这是我的工作代码:

\n\n
    private async Task Connect(bool dismissCurrentConnection = false)\n    {\n        // Always create a new connection to avoid SignalR close event delays\n        if (connection != null)\n        {\n            if (!dismissCurrentConnection)\n            {\n                return;\n            }\n\n            connection.StateChanged -= OnConnectionStateChangedHandler;\n            connection.Reconnected -= OnReconnectedHandler;\n            // DON\xc2\xb4T call connection.Dispose() or it may block for 20 seconds\n            connection = null;\n            proxy = null;\n        }\n\n        connection = new HubConnection(Settings.SERVER);\n        // connection.TransportConnectTimeout = TimeSpan.FromSeconds(5);\n        connection.TraceWriter = tracer;\n        connection.TraceLevel = TraceLevels.All;\n        connection.StateChanged += OnConnectionStateChangedHandler;\n        connection.Reconnected += OnReconnectedHandler;\n\n        proxy = connection.CreateHubProxy("ChatHub");\n        proxy.On<ChatMessage>("AddNewMessage", message => AddNewMessage(message));\n        proxy.On<ChatMessage>("ConfirmMessageDelivered", Message => ConfirmMessageDelivered(Message));\n        proxy.On<string>("ConfirmMessageReceived", uid => ConfirmMessageReceived(uid));\n        proxy.On<string>("ConfirmMessageRead", uid => ConfirmMessageRead(uid));\n        proxy.On<UserChatStatus>("ChangeUserChatStatus", status => ChangeUserChatStatus(status));\n\n        if (connection.State == ConnectionState.Disconnected)\n        {\n            try\n            {\n                MvxTrace.Trace("[{0}] Connecting...", nameof(ChatService));\n                await connection.Start();\n                await invokeQueue.ProcessQueue();\n            }\n            catch (Exception ex)\n            {\n                MvxTrace.Error("[{0}] CONNECTION START ERROR: {1}", nameof(ChatService), ex.Message);\n            }\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

第一次我将使用await Connect()连接;\n后续连接将使用await Connect(true)来关闭当前连接

\n\n
    private void OnReconnectedHandler()\n    {\n        Task.Factory.StartNew(async () => await invokeQueue.ProcessQueue());\n    }\n\n    private void OnConnectionStateChangedHandler(StateChange change)\n    {\n        this.ConnectionState = change.NewState;\n        OnConnectionStateChanged?.Invoke(change);\n\n        switch (change.NewState)\n        {\n            case ConnectionState.Disconnected:\n                // SignalR doesn\xc2\xb4t do anything after disconnected state, so we need to manually reconnect\n                reconnectTokenSource = new CancellationTokenSource();\n                Task.Factory.StartNew(async () =>\n                {\n                    await Task.Delay(TimeSpan.FromSeconds(Settings.RECONNECT_PERIOD_SECONDS), reconnectTokenSource.Token);\n                    await Connect(true);\n                }, reconnectTokenSource.Token);\n\n                break;\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您想知道什么是“invokeQueue”,它\xc2\xb4只是一个自定义实用程序,可以在状态未连接时捕获所有信号器代理调用,并在连接恢复后处理它们。

\n\n

如果我不\xc2\xb4不想继续重新连接过程(即:关闭活动时),“reconnectTokenSource”将被取消。

\n\n

看起来我们的配置非常相似。唯一明显的区别是,您\xc2\xb4re 在 Android 项目中使用 nuget,而我\xc2\xb4m 在 PCL 上使用它。

\n\n

在此日志中您可以检查断开连接事件:

\n\n
mvx:Diagnostic: 14,72 [SignalRTracer] 01:47:56.2406950 - null - ChangeState(Disconnected, Connecting)\nmvx:Diagnostic: 15,48 [SignalRTracer] 01:47:57.0176730 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - SSE: GET http://192.168.0.53/signalr/connect?clientProtocol=1.4&transport=serverSentEvents&connectionData=[{"Name":"ChatHub"}]&connectionToken=IgMS6rxmjHJCeudFlDRV8jFSt9Tz1Mt210X21RbiFAIalj%2BioMMRWPH5%2BfNaNIkVW%2BzHbv%2FmSjk8uoRNVbK%2FKUL%2FI87iBkejKkXYivq5FZy6x8E1%2FAK2rBnCg3Zi9nwY&noCache=d4878c0b-5c2a-4535-929c-29952f5e6795\nmvx:Diagnostic: 15,56 [SignalRTracer] 01:47:57.0945740 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - SSE: OnMessage(Data: initialized)\nmvx:Diagnostic: 15,57 [SignalRTracer] 01:47:57.1054290 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - SSE: OnMessage(Data: {"C":"d-3050D8AB-B,C|I,0|J,1","S":1,"M":[]})\nmvx:Diagnostic: 15,70 [SignalRTracer] 01:47:57.2408050 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - ChangeState(Connecting, Connected)\nmvx:Diagnostic: 15,82 [SignalRTracer] 01:47:57.3586480 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - SSE: OnMessage(Data: {"C":"d-3050D8AB-B,D|I,0|J,1","M":[]})\nmvx:Diagnostic: 15,83 [SignalRTracer] 01:47:57.3718630 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - OnMessage({"I":"0"})\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后我关掉了wifi:

\n\n
mvx:Diagnostic: 29,55 [SignalRTracer] 01:48:11.0813880 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - OnError(System.Net.Sockets.SocketException: Connection timed out at System.Net.Sockets.Socket.EndReceive (IAsyncResult result) [0x0002d] in /Users/builder/data/lanes/2098/3efa14c4/source/mono/mcs/class/System/System.Net.Sockets/Socket.cs:1798 at System.Net.Sockets.NetworkStream.EndRead (IAsyncResult ar) [0x0002f] in /Users/builder/data/lanes/2098/3efa14c4/source/mono/mcs/class/System/System.Net.Sockets/NetworkStream.cs:320 )\nmvx:Diagnostic: 31,56 [SignalRTracer] 01:48:13.1037440 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - ChangeState(Connected, Reconnecting)\nmvx:Diagnostic: 31,68 [SignalRTracer] 01:48:13.2199720 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - OnError(System.Net.Sockets.SocketException: Network is unreachable at System.Net.Sockets.Socket.Connect (System.Net.EndPoint remoteEP) [0x000bc] in /Users/builder/data/lanes/2098/3efa14c4/source/mono/mcs/class/System/System.Net.Sockets/Socket.cs:1235 at System.Net.WebConnection.Connect (System.Net.HttpWebRequest request) [0x0019b] in /Users/builder/data/lanes/2098/3efa14c4/source/mono/mcs/class/System/System.Net/WebConnection.cs:213 )\n
Run Code Online (Sandbox Code Playgroud)\n\n

稍后的...

\n\n
mvx:Diagnostic: 61,68 [SignalRTracer] 01:48:43.2182200 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - OnError(System.TimeoutException: Couldn\'t reconnect within the configured timeout of 00:00:30, disconnecting.)\nmvx:Diagnostic: 61,69 [SignalRTracer] 01:48:43.2330650 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - Disconnected\nmvx:Diagnostic: 61,76 [SignalRTracer] 01:48:43.2972460 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - Transport.Dispose(6dd879af-7d49-4632-96b2-cb5fb542dc24)\nmvx:Diagnostic: 61,77 [SignalRTracer] 01:48:43.3065810 - 6dd879af-7d49-4632-96b2-cb5fb542dc24 - Closed\n
Run Code Online (Sandbox Code Playgroud)\n