我有两个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实施故障转移解决方案的一些最佳实践将非常感激。
我也知道背板横向扩展方法,但我相信上面的问题也会出现在那里。
答案 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 >
是一组两个键,它不是随机字符串,并且具有自己的格式。一旦您知道需要,就不应该找到如何生成它的问题:)