Search code examples
angulartypescriptasp.net-coresignalraspnetboilerplate

Multiple SignalR connections in ABP


I have a project that is using ASP.NET Zero template. I have successfully integrated SignalR into my solution and the real-time notification works fine. What I want is adding another hub to my solution or extending the existing SignalR hub to add more to it.

In the SignalR AspNetCore Integration document, it says to add the following to the Startup.cs file:

app.UseSignalR(routes =>
{
     routes.MapHub<AbpCommonHub>("/signalr"); // default hub
     routes.MapHub<HitchNotification.HitchHub>("/hitchHub"); // my hub
});

The issue, however, is the client where I need to set up the connection! In the SignalRAspNetCoreHelper.ts, it sets the URL to use the '/signalr' hub (default one).

export class SignalRAspNetCoreHelper {
    static initSignalR(): void {

        var encryptedAuthToken = new UtilsService().getCookieValue(AppConsts.authorization.encrptedAuthTokenName);

        abp.signalr = {
            autoConnect: true,
            connect: undefined,
            hubs: undefined,
            qs: AppConsts.authorization.encrptedAuthTokenName + "=" + encodeURIComponent(encryptedAuthToken),
            url: AppConsts.remoteServiceBaseUrl + '/signalr'
        };

        jQuery.getScript(AppConsts.appBaseUrl + '/assets/abp/abp.signalr-client.js');
    }
}

If I change the '/signalr' to '/hitchHub', it works fine. But I want both in my application! I tried to create a helper for my own hub similar to the SignalRAspNetCoreHelper.ts and initialize it in the app.component.ts:

ngOnInit(): void {
    if (this.appSession.application && this.appSession.application.features['SignalR']) {
        if (this.appSession.application.features['SignalR.AspNetCore']) {
            SignalRAspNetCoreHelper.initSignalR();
            HitchHubHelper.initHitchHub();  
        } 
    }
}

But it seems that the abp.signalr can't have multiple connections to different hubs.

So, basically I have 2 questions:

  1. Is there any way that I could add my own hub's functions to the default AbpCommonHub? That way, I could simply modify the abp.signalr-client.js file.

  2. If the above is impossible, how can I have multiple hubs on the abp.signalr to be accessible anywhere within my application?


Solution

    1. Is there any way that I could add my own hub's functions to the existing default AbpCommonHub? that way I could simply modify the abp.signalr-client file

    Sure. Inherit AbpCommonHub:

    public class HitchHub: AbpCommonHub
    {
        // Ctor omitted for brevity
    
        public async Task SendMessage(string message)
        {
            await Clients.All.SendAsync("getMessage", string.Format("User {0}: {1}", AbpSession.UserId, message));
        }
    }
    

    Replace hub:

    // routes.MapHub<AbpCommonHub>("/signalr");
    routes.MapHub<HitchHub>("/signalr");
    
    1. If the above is impossible, how can I have multiple hubs on the abp.signalr to be accessible anywhere within my application?

    The above is not impossible, but I'll answer this anyway to demonstrate multiple hubs (for Angular).

    Inherit AbpHubBase:

    public class HitchHub : AbpHubBase, ITransientDependency
    {
        public async Task SendMessage(string message)
        {
            await Clients.All.SendAsync("getMessage", string.Format("User {0}: {1}", AbpSession.UserId, message));
        }
    }
    

    Map hub:

    routes.MapHub<AbpCommonHub>("/signalr"); // No change
    routes.MapHub<HitchHub>("/signalr-hitchHub"); // Prefix with '/signalr'
    

    Usage

    This requires Abp.AspNetCore.SignalR v3.5.0-preview3.

    Modify SignalRAspNetCoreHelper.ts:

    abp.signalr = {
        autoConnect: true,  // No change
        connect: undefined, // No change
        hubs: undefined,    // No change
        qs: AppConsts.authorization.encrptedAuthTokenName + "=" + ... // No change
        remoteServiceBaseUrl: AppConsts.remoteServiceBaseUrl,         // Add this
        startConnection: undefined,                                   // Add this
        url: '/signalr' // Changed from: AppConsts.remoteServiceBaseUrl + '/signalr'
    };
    
    // Modify the following block
    jQuery.getScript(AppConsts.appBaseUrl + '/assets/abp/abp.signalr-client.js', () => {
        var hitchHub;
    
        abp.signalr.startConnection('/signalr-hitchHub', function (connection) {
            hitchHub = connection; // Save a reference to the hub
    
            connection.on('getMessage', function (message) { // Register for incoming messages
                console.log('received message: ' + message);
            });
        }).then(function (connection) {
            abp.log.debug('Connected to hitchHub server!');
            abp.event.trigger('hitchHub.connected');
        });
    
        abp.event.on('hitchHub.connected', function() { // Register for connect event
            hitchHub.invoke('sendMessage', "Hi everybody, I'm connected to the chat!"); // Send a message to the server
        });
    });