我有一个在我的开发环境中没有问题的SignalR项目但是一旦它被转移到生产中,几乎每个调用都会因错误而失败
ConnectionId的格式不正确。
我在StackOverflow上看到了一些关于相同错误消息的其他项目,但没有一个项目有一个有帮助的解决方案。
我正在使用SignalR 2.0.2和SignalR Scaleout with SQL Server,实际上是SignalR的负载均衡器,它使用SQL Server进行协调。
事件代码:3005事件消息:发生了未处理的异常。 活动时间:2/11/2014 9:11:27 PM活动时间(UTC):2014年2月2日3:11:27 AM事件ID:cff1fd93fa6d4b83b1848078a905371c事件序列:73 事件发生:10事件详细信息代码:0应用程序信息:
Application domain: /LM/W3SVC/2/ROOT-3-130366479327251392 Trust level: Full Application Virtual Path: / Application Path: C:\inetpub\wwwroot\<remvoved> Machine name: BSDUSHC1WW09 Process information: Process ID: 7088 Process name: w3wp.exe Account name: <remvoved> Exception information: Exception type: InvalidOperationException Exception message: The ConnectionId is in the incorrect format. at
Microsoft.AspNet.SignalR.PersistentConnection.GetConnectionId(HostContext context,String connectionToken)at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext 上下文) Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ProcessRequest(HostContext 上下文) Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(IDictionary`2 环境) Microsoft.Owin.Mapping.MapMiddleware.d__0.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束--- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult的 一只老鼠 System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 在System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤, 布尔和放大器; completedSynchronously)
请求信息: 请求URL:http:/// signalr /连接运输= serverSentEvents&安培; connectionToken = GZlhDBCjkD1 / bL1rc4Rlq2PVKYRs0B9nN7b71cU / E6x7sCsFvR1DqM / rBnDhg + URwkYyBlGmrczV59XIn / goyt9x0xXOd8Gs3Qswo1oXqSttH2QPO548C0fbdBvvlUupzS4S0Rl + aShoQwnj + qFDpA ==&安培; connectionData = [{ “名称”: “”}] < / p>
Request path: /signalr/connect User host address: 10.240.14.26 User: <remvoved> Is authenticated: True Authentication Type: Negotiate Thread account name: <remvoved> Thread information: Thread ID: 23 Thread account name: <remvoved> Is impersonating: False Stack trace: at Microsoft.AspNet.SignalR.PersistentConnection.GetConnectionId(HostContext
context,String connectionToken)at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext 上下文) Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ProcessRequest(HostContext 上下文) Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(IDictionary`2 环境) Microsoft.Owin.Mapping.MapMiddleware.d__0.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束--- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult的 一只老鼠 System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 在System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤, 布尔和放大器; completedSynchronously)
答案 0 :(得分:20)
就像负载平衡使用Session的ASP.NET网站一样,SignalR与SQL Server Scaleout要求处理SignalR请求的所有服务器必须共享机器密钥。
在SignalR的文档中没有明显提到这一点,因此我必须假设上述事件日志消息中的connectionToken
是使用机器密钥加密的。当应用程序到达服务器1时,将为其分配使用该计算机的机器密钥生成的connectionToken。如果应用程序随后使用分配的connectionToken命中服务器2,则机器2无法解密该令牌,除非它具有匹配的机器密钥。
网上有无数关于如何设置机器密钥的资源,所以我会留下最简单的资源。单击IIS 8中的网站(也可能是7)并打开机器密钥设置。点击右侧操作窗格中的Generate Keys
。取消选中Validation Key
和Decryption Key
部分下的'为每个应用生成唯一键'复选框。
答案 1 :(得分:3)
虽然凯文已经回答了这个问题(这有助于我和我的投票),但是在为服务器场中的每台服务器配置相同的机器密钥之后,问题仍然存在(有时奇怪地随机工作,但第一次尝试总是失败的。)
您还需要确保每个服务器中的应用程序使用相同的凭据运行。在我的方案中,应用程序池配置为在网络服务(通过网络呈现自己的计算机凭据)下运行。由于每个服务器都有自己的凭据,因此它们不相同,因此问题尚未解决。
我必须创建一个可以访问服务器场中每个服务器的用户,并使每个服务器中的应用程序与该用户一起运行。只有在这样做之后我的问题才得以解决。