I have a SignalR project that was working without issue in my development environments but once it was moved to production almost every call would fail with the error
The ConnectionId is in the incorrect format.
I saw a few other items on StackOverflow about the same error message but none of them had a solution that helped.
I am using SignalR 2.0.2 and SignalR Scaleout with SQL Server, effectively a load balancer for SignalR that uses SQL Server for coordination.
Event code: 3005 Event message: An unhandled exception has occurred. Event time: 2/11/2014 9:11:27 PM Event time (UTC): 2/12/2014 3:11:27 AM Event ID: cff1fd93fa6d4b83b1848078a905371c Event sequence: 73 Event occurrence: 10 Event detail code: 0 Application information:
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 context) at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ProcessRequest(HostContext context) at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(IDictionary`2 environment) at Microsoft.Owin.Mapping.MapMiddleware.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Request information: Request URL: http:///signalr/connect?transport=serverSentEvents&connectionToken=GZlhDBCjkD1/bL1rc4Rlq2PVKYRs0B9nN7b71cU/E6x7sCsFvR1DqM/rBnDhg+URwkYyBlGmrczV59XIn/goyt9x0xXOd8Gs3Qswo1oXqSttH2QPO548C0fbdBvvlUupzS4S0Rl+aShoQwnj+qFDpA==&connectionData=[{"Name":""}]
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 context) at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ProcessRequest(HostContext context) at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(IDictionary`2 environment) at Microsoft.Owin.Mapping.MapMiddleware.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Each client connecting to a hub passes a unique connection id. You can retrieve this value in the Context. ConnectionId property of the hub context.
If your SignalR application transmits sensitive information between the client and server, use SSL for the transport.
At any time a user could have more than one connection to the SignalR application. For example, a user who is connected through multiple devices or more than one browser tab would have more than one connection id. If the application shuts down, all of the information is lost, but it will be re-populated as the users re-establish their connections.
If you have questions that are not directly related to the tutorial, you can post them to the ASP.NET SignalR forum or StackOverflow.com. Each client connecting to a hub passes a unique connection id.
The dictionary uses a HashSet to store the connection id. At any time a user could have more than one connection to the SignalR application. For example, a user who is connected through multiple devices or more than one browser tab would have more than one connection id.
I saw a few other items on StackOverflow about the same error message but none of them had a solution that helped. I am using SignalR 2.0.2 and SignalR Scaleout with SQL Server, effectively a load balancer for SignalR that uses SQL Server for coordination.
Just like when load balancing an ASP.NET website that uses Session, SignalR with SQL Server Scaleout requires that all servers which handle SignalR requests must share a machine key.
There is no obvious mention of this in the documentation for SignalR so I have to assume the connectionToken
in the above event log message is encrypted using the machine key. When an application hits server 1 it is assigned a connectionToken generated using that machine's machine key. If the application then hits server 2 with that assigned connectionToken, machine 2 cannot decrypt the token unless is has a matching machine key.
There are countless resources online about how to set a machine key so I'll leave just the easiest one. Click on the website in IIS 8 (maybe 7 too) and open the Machine Key settings. Click Generate Keys
in the actions pane on the right. Uncheck the 'Generate a unique key for each application' checkbox under both the Validation Key
and Decryption Key
sections.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With