Maintaining SignalR ConnectionId’s Across Page Instances

 2/28/2013 – With the 1.0 release of SignalR, I can’t guarantee the solution below will work the same.  The big problem with this solution is that ConnectionIds are reused across tabs and browser windows since it’s cookie based.  You might not have the results you’re expecting.  The SignalR team doesn’t recommend this action, and I can agree.  I didn’t see it when I wrote the post.  This is a decent guide for overriding the connection id factory, so I’ll leave it up for archival purposes.

I’m a huge fan of SignalR, and today I was looking at a particular problem.  I would think it’s more of a feature, but in certain use cases it can be considered a bug.

When you start a connection to SignalR for the first time, you are assigned a ConnectionId.  SignalR uses this to determine what messages should go to you, and allows the server to direct messaging at a particular user.

If you were to refresh the page, SignalR will assign you a NEW ConnectionId.  This could be good or bad… but if you’re trying to maintain some sense of state between your clients and the hub, it’s bad.

So I looked into how to make SignalR reuse ConnectionIds in the case of a page refresh.  There are really two steps involved.

1) Set a cookie on the client

When you start() a new connection, SignalR will return a ConnectionId.  You’ll want to set a cookie with that ConnectionId in it.

As you can see, this gets the ConnectionId from the hub connection and stores it in a cookie.

2) Use your own IConnectionIdFactory

This might be scary territory for you, but it’s actually pretty simple.  We want to create our own version of the IConnectionIdFactory interface for SignalR to use.

This does two things.  First, it’ll check your cookie for a ConnectionId it should use.  If it exists, we’ll simply return that ConnectionId and all will be good in the world.

If the cookie does NOT exist, we need to generate one.  By default, SignalR uses a GUID, so we’ll just repeat that functionality.  You can use any value you want, but make sure it’s unique.

Don’t forget to wire it up!  Add this to you Global.asax file under Application_Start().

And you’re all set!  SignalR will now use your new ConnectionIdFactory to generate or reuse ConnectionIds.

Enjoy!

Kevin Griffin
@1kevgriff


Do your Windows Servers need an easy monitoring solution? Try Winsitter today!

Don't forget to follow me on Twitter! I'm @1kevgriff

Have the bytes gotten you bit? When in doubt, Consult with Griff
  • Jason Follas

    I’m trying to picture a scenario where you would need to maintain the connection id between page refreshes.  Can you provide an example?

    • http://www.kevgriffin.com/ Kevin Griffin

      For my needs, I want to be able to quickly rebuild a page state from the server. Since I’m mapping ConnectionId’s to internal user accounts, it’s quick and easy if the ConnectionId’s are the same.

      • Hichem

        Hello Kevin,
        Good work, Can you please tell us how do you make the mapping between connectioId and user accounts, where do you keep them. I want to make a notification system like facebook, so i want to notify only one user for each action. 
        Thx

        • http://www.kevgriffin.com/ Kevin Griffin

          That’s a topic for another blog post.  I’ll work on something.

          • chinky a

            Is the next topic on the blog anywhere? I am exactly trying the same scenario for mapping user accounts with connection id

  • Baris akpunar

    i think the code for Application_Start() is wrong.

    • http://www.kevgriffin.com/ Kevin Griffin

      Looks fine to me.

      • Somineni3

        change it to like this
        AspNetHost.DependencyResolver.Register(typeof(IConnectionIdFactory), () => new MyConnectionFactory());

        • http://www.kevgriffin.com/ Kevin Griffin

          Oh, the code just got escaped.  It’s the same difference.  I think most people are smart enough to figure it out.

          • Somineni3

            hi Kevin i have tried your code but for my mvc app the cookie is always null in the MyconnectionFactory class

          • http://www.kevgriffin.com/ Kevin Griffin

            It will always be null first time you connect to the hub.  The cookie isn’t populated until after the first time a connectionid is generated.

  • M Zorn

    Is there any other way to pass information to the Connection Factory besides using a cookie? Want to avoid the situation where a person has cookies disabled.

    • http://www.kevgriffin.com/ Kevin Griffin

      Not that I can see.  The ConnectionIDFactory is very slim!

  • Guest

    One hint: you should set the path of the cookie (e.g. “document.cookie = cName + “=” + c_value + ‘; path=/’; “). Otherwise, if your page is located in a subdirectory, “request.Cookies["srconnectionid"]” is always null and therefore you will get a new ConnectionID when reloading the page.

  • http://twitter.com/amitava82 Amitava Saha

    OK, I did exactly what the post said, but it did not work. Could you please share your sample project.

  • Imran

    I was in your presentation of SignalR.

    My question is:

    If I want to consume your application broadcast application that you implemented in my machine. Basically my machine will be client.
    How to do this. 
    Do I need to consume in the same manner what we are doing upto now. I mean in project we need to add service reference and then create an instance of it and pass the appropriate parameter to a method that exist.

    Looking forward to hearing from you.

  • http://www.facebook.com/elleryfamilia Ellery Familia

    Any way to use HTML5 localStorage instead of cookie? I guess the issue would be how’d you access that info from the server

  • Julien Rosen

    How does one accomplish this when the SignalR server is seperate from the Asp.Net web server?  The cookie is sent to Asp.Net server and not the SignalR request.

  • http://twitter.com/swingsetacid Joshua Ewer

    Works beautifully.  Thanks for the help!

  • Giolvani

    The code in Application_Start() does not work in .NET framework 4.0?

    Any suggestions?

    • http://www.kevgriffin.com/ Kevin Griffin

      With the current release of SignalR v1.0, I’ll need to revisit this post to determine consider possible issues.

      • Giolvani

        I am using SignalR 0.5.3, but if you do the revision, we will be very happy! :D
        Tks

    • http://www.kevgriffin.com/ Kevin Griffin

      BTW, “does not work” is pretty subjective. Are you getting an exception?

  • kurai

    any updates?