Search code examples
asp.net-mvcsignalrcross-domainsignalr-2.net-4.7.2

Sharing connections between two SignalR Hubs on different domains


I currently have a live chat website set up that hits a subdomain responsible for handling SignalR interactions:

www.domain1.com > chat.domain1.com

I'm wanting to introduce a second, duplicate, largely identical site using the same structure:

www.domain2.com > chat.domain2.com

Both sites will use the same database, which stores all persistent SignalR related things like connections, chat rooms, chat messages, etc.

Is it possible for both SignalR chat subdomains to communicate with clients connected to the other subdomain? While the shared database means that persistent resources are shared, I need to make it so that when I publish an event on chat.domain1.com clients connected to both chat.domain1.com and chat.domain2.com receive them.

It appears that it is common to handle this by sharing the same domain and using CORS to handle cross-domain interactions like so:

www.domain1.com  
                > chat.domain1.com
www.domain2.com

I can't do this as the SignalR chat endpoints authenticate using cookies set on the main www domain. Those cookies can't be shared cross-domain and even if they could, it's a requirement that a user has the ability to be logged in simultaneously to different accounts on domain1.com and domain2.com on the same machine.

So, are there any approaches I can use to share connections between these two hubs? Both chat subdomains are hosted on the same server?


Solution

  • Typically a backplane is used when your app is being scaled out across multiple servers however it also appeared to work in this situation. I used SQL Server for the backplane but there are also packages to get this working with Redis and Azure Service Bus.


    First install the package for SQL Server:

    Install-Package Microsoft.AspNet.SignalR.SqlServer
    

    Then configure the backplane:

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            string sqlConnectionString = "Connecton string to your SQL DB";
            GlobalHost.DependencyResolver.UseSqlServer(sqlConnectionString);
            app.MapSignalR();
        }
    }
    

    This allows SignalR to use SQL Server to persist any messages it needs to distribute. The first time it starts up it creates a few tables in the database and you're good to go:

    Database created for SignalR backplane

    Because both apps share the same database, this works perfectly.