SignalR主动/被动故障转移设置

时间:2018-04-04 14:00:50

标签: c# websocket signalr load-balancing failover

我有两个SignalR服务器位于HaProxy负载均衡器后面,配置了主动/被动配置。

每次将所有请求转发到一个节点。我们可以说,node1是有效的,node2是热门和准备好的,但由于node1在线,因此无法接收来自LB的任何流量。

当用户打开网页时,SignalR客户端通过LB连接到node1。假设我们有一个客户端连接到我们的服务器。

node1发生故障时,HaProxy会将流量切换到node2,并通过SignalR检测已连接的客户端是否已断开连接并尝试重新连接呼叫。虽然node2已启动并正在运行,但客户端会因重新连接而出现错误,如下所示:

WebSocket connection to 'ws://10.0.11.88:12000/signalr/reconnect?transport=webSockets&messageId=s-0%2C12A&clientProtocol=1.5&myparam1=1&myparam2=6&token=6372bdbd1ca64f06aa52362a6913bdd8&connectionToken=lxqeSwxAu756vF0TwhXCFzb0ZMHraRocsx7jS2A%2F%2Ben0vgtfI9Fid47oLiKg4KnX3E5eFKwwaezv4JSPbrsLr3C%2FmTGS8Ev3WLgAUZcbAjvlf9VHYsxbEcYV7Z09rHEH&connectionData=%5B%7B%22name%22%3A%22gamewindow%22%7D%5D&tid=7' failed: Error during WebSocket handshake: Unexpected response code: 400

在visual studio中浏览输出时,我发现了以下错误日志:

SignalR.HubDispatcher Information: 0 : Failed to process connectionToken lxqeSwxAu756vF0TwhXCFzb0ZMHraRocsx7jS2A/+en0vgtfI9Fid47oLiKg4KnX3E5eFKwwaezv4JSPbrsLr3C/mTGS8Ev3WLgAUZcbAjvlf9VHYsxbEcYV7Z09rHEH: System.Security.Cryptography.CryptographicException: Error occurred during a cryptographic operation. at System.Web.Security.Cryptography.HomogenizingCryptoServiceWrapper.HomogenizeErrors(Func`2 func, Byte[] input) at Microsoft.AspNet.SignalR.Infrastructure.DataProtectionProviderProtectedData.Unprotect(String protectedValue, String purpose) at Microsoft.AspNet.SignalR.PersistentConnection.TryGetConnectionId(HostContext context, String connectionToken, String& connectionId, String& message, Int32& statusCode)

在重新连接尝试首先连接到客户端所连接的同一服务器的情况下,即使服务器应用程序完全重新启动,一切正常。

对于此错误的任何见解或有关如何为SignalR实施故障转移解决方案的一些最佳实践将非常感激。

我也知道背板横向扩展方法,但我相信上面的问题也会出现在那里。

1 个答案:

答案 0 :(得分:0)

经过一番研究,发现了修复。

为什么我会收到CryptographicException :SignalR使用一些加密技术来处理connectionId的安全问题。对于散列,它使用machineKey,默认情况下由IIS静默生成并在运行时注入web.config。因此,我的两台服务器获得了两种不同的machineKey配置,这就是为什么SignalR客户端无法重新连接到node2,但重新连接到node1即使在machineKey之后也是如此; s重启。

修复是禁用IIS中的自动machineKey生成(IIS管理器中有一个名称相同的部分),并为两个节点提供相同的node2配置。完成此操作后,当node1断开连接时,SignalR客户端重新连接到machineKey,没有任何问题。

另请注意,<asp:TemplateField HeaderText="Accepté" ControlStyle-Width="90px"> <ItemTemplate > <asp:Label ID="lblState" runat="server" Text='<%# Eval("StateCode") %>' Visible = "False" /> <asp:DropDownList ID="ddlState" runat="server" Visible = "False" OnSelectedIndexChanged="ddlState_SelectedIndexChanged"> </asp:DropDownList> </ItemTemplate> </asp:TemplateField > 是一组两个键,它不是随机字符串,并且具有自己的格式。一旦您知道需要,就不应该找到如何生成它的问题:)