Andrius Naruševičius
Andrius Naruševičius

Reputation: 8578

SignalR: The connection id is in the incorrect format. How to deal with it when the session expires?

I have come up with a well known SignalR problem which gives multiple results when googled "The connection id is in the incorrect format." However I cannot find the solution that would fit my needs. All the solutions suggested are the same: stop signalR in javascript in client. However, what I need is to somehow stop or handle the error in server side.

Example: the user logs in, SignalR starts, all is good, he clicks logout (just before the logout I override javascript event and stop SignalR). No error.

Another example: the user logs in, SignalR starts, user waits for some time the session ends. He clicks something, he is thrown to login page. However, SignalR now notices the User's Identity has changed and throws this error The connection id is in the incorrect format. Add a few of these happening and I have my IIS Worker working at 100% CPU thus resulting in a crashed server. A bit modified example would include SignalR pinging the server and again seeing that the session has ended and thus throwing an exception.

How should I handle such issue? Is there a way to stop SignalR for certain client from server side? Or maybe something different? Maybe I can make SignalR somehow stop relying on Identity? I am sure people must have somehow solved this already. I am using Forms authentication and MVC4 in my project. The version of SignalR is 1.0.0. I know it isn't latest, but I doubt it would do any good if it was the latest. Or maybe someone has proof that I am wrong?

I am adding the information of the error from my IIS logs just in case:

Exception information: 
    Exception type: InvalidOperationException 
    Exception message: 

Server stack trace: 
   at Microsoft.AspNet.SignalR.PersistentConnection.GetConnectionId(HostContext context, String connectionToken)
   at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext context)
   at Microsoft.AspNet.SignalR.Owin.CallHandler.Invoke(IDictionary`2 environment)
   at Microsoft.AspNet.SignalR.Owin.Handlers.HubDispatcherHandler.Invoke(IDictionary`2 environment)
   at Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute()
   at Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object extraData)

Exception rethrown at [0]: 
   at Microsoft.Owin.Host.SystemWeb.Utils.<>c__DisplayClass1.<GetRethrowWithNoStackLossDelegate>b__0(Exception ex)
   at Microsoft.Owin.Host.SystemWeb.CallContextAsyncResult.End(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)



Request information: 
    Request URL: http://example.com:port/signalr/abort?transport=serverSentEvents&connectionToken=0D8V3TwV78z1cU7_kbQGaSjZH1r_w4eGkkFPRftDiZXPJjbEZmXEluSOkvzVBDRQOGWzVPGfeCKdsvEUwhzb07-Kph-pJ3oog_ydjvsRSnoXqDnYZkPXwJgPrFsFYtmpFDKe0hOvHS7ZxApQF_4fbw2 
    Request path: /signalr/abort 
    User host address: A.B.C.D 
    User:  
    Is authenticated: False 
    Authentication Type:  
    Thread account name: IIS APPPOOL\DefaultAppPool 

Thread information: 
    Thread ID: 63 
    Thread account name: IIS APPPOOL\DefaultAppPool 
    Is impersonating: False 
    Stack trace:    at Microsoft.Owin.Host.SystemWeb.Utils.<>c__DisplayClass1.<GetRethrowWithNoStackLossDelegate>b__0(Exception ex)
   at Microsoft.Owin.Host.SystemWeb.CallContextAsyncResult.End(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Upvotes: 2

Views: 1496

Answers (3)

Wasp
Wasp

Reputation: 3425

Just "thinking out loud", if the problem is just because of the session expiration, you might want to try to intercept when the session ends on the server and broadcast a message to all impacted clients (logic to be added for this) asking them to disconnect explicitly and avoid them thrashing your server. I guess your session is tied to authentication so a login would have to happen anyway, so you would reconnect SignalR after that. Makes sense?

You could also have a client side timeout expiring after N-1 minutes, where N is the duration of the Session. and have that one force a disconnection. The timeout itself could be updated using SignalR itself if things happening on the server make the time window move.

Both are pragmatic, quick and dirty solutions, to keep both SignalR and Session together.

Upvotes: 1

user3383479
user3383479

Reputation:

You can find a good explanation in this thread. It seems you can't somehow use Session with SignalR. I hope it will help you.

Upvotes: 0

Related Questions