Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR Server Error "The ConnectionId is in the incorrect format." with SignalR-ObjC Library

Before asking a separate question I've done lots of googling about it and added a comment in the already existing stackoverflow question.

I have a SignalR Hub (tried both v. 1.1.3 and 2.0.0-rc) in my server with the below code:

    [HubName("TestHub")]
    public class TestHub : Hub
    {
            [Authorize]
            public void TestMethod(string test)
            {
                //some stuff here
                Clients.Caller.NotifyOnTestCompleted();
            }
    }

The problem persists if I remove the Authorize attribute.

And in my iOS client I try to call it with the below code:

    SRHubConnection *hubConnection = [SRHubConnection connectionWithURL:_baseURL];
    SRHubProxy *hubProxy = [hubConnection createHubProxy:@"TestHub"];
    [hubProxy on:@"NotifyOnTestCompleted" perform:self selector:@selector(stopConnection)];

    hubConnection.started = ^{
        [hubProxy invoke:@"TestMethod" withArgs:@[@"test"]];
    };

    //received, error handling
    [hubConnection start];

When the app starts the user is not logged in and there is no open SignalR connection. The users logs in by calling a Login service in the server which makes use of WebSecurity.Login method. If the login service returns success I then make the above call to SignalR Hub and I get the server error 500 with description "The ConnectionId is in the incorrect format.".

The full server stacktrace is the following:

    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.<Invoke>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://myserverip/signalr/signalr/connect?transport=webSockets&connectionToken=axJs EQMZxpmUopL36owSUkdhNs85E0fyB2XvV5R5znZfXYI/CiPbTRQ3kASc3 mq60cLkZU7coYo1P fbC0U1LR2rI6WIvCNIMOmv/mHut/Unt9mX3XFkQb053DmWgCan5zHA==&connectionData=[{"Name":"testhub"}] 
        Request path: /signalr/signalr/connect 
        User host address: 
        User:  
        Is authenticated: False 
        Authentication Type:  
        Thread account name: IIS APPPOOL\DefaultAppPool 

    Thread information: 
        Thread ID: 14 
        Thread account name: IIS APPPOOL\DefaultAppPool 
        Is impersonating: True 
        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.<Invoke>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)

I understand this is some kind of authentication and user identity mismatching but up to now I have found no way of solving it. All other questions suggest stoping the opened connection when the user identity changes but as I mentioned above I have no open connection before the user logs in successfully.

Any help would be much appreciated. Thank you.

like image 436
ozzotto Avatar asked Sep 24 '13 10:09

ozzotto


2 Answers

Here is what I found, I am trying to create a Flex/AS3 client for signalR. It only uses websockets but for my work I control both ends of the system so I know my backend will support it.

Anyway, the trick to getting around this for me was encoding the connectionToken. The server side signalR code is trying to parse out the connection ID from the token. When you get the token from the server it comes as part of the negotiation handshake, when you try to send it back you must make sure to remove the "/" and "+" symbols and encode them as %2F and %2B respectively. In AS3 the escape or other equivalent url encoding methods left the slash presumably because it is a valid url character, but since the value is passed in the querystring it needs to be encoded.

Once I did this I stopped getting a server 500 error (The ConnectionId is in the incorrect format) and the socket opened and I received messages.

Hope this helps.

Jason

like image 199
jmichas Avatar answered Oct 11 '22 12:10

jmichas


Looks like you are using https://github.com/DyKnow/SignalR-ObjC be sure to use the feature-2.0.0.beta1 branch until it is pulled into master.

like image 32
DalSoft Avatar answered Oct 11 '22 12:10

DalSoft