Base solution for your next web application
Ends in:
01 DAYS
01 HRS
01 MIN
01 SEC
Open Closed

Notifications using SignalR and Redis BackPlane #4337


User avatar
0
devkev2403 created

Hi,

I have an ASP.NET Module Zero application (ASP.NET Core targetting .NET 4.6) that runs on multiple servers. The servers are behind a load balancer.

The application publishes a notification. The application is configured to use Redis (and it's pub/sub model) as a backplane. The idea here is that the notification from the server gets written to the Redis backplane, the Redis backplane then notifies all the other servers (that are Redis subscribers) and the other servers then using the ABP Zero notification system send the notification to all it's connected clients using SignalR.

Publishing the notification is ok and it gets written/published to the Redis backplane. All servers/subscribers get the Redis message ok (I can see it using redis-cli). The problem I have is that only the clients connected to 1 server get a SignalR message to act on (e.g. display a model and update the notification count in the top right corner).

I know this is a needle in a hay stack, but am I missing some obvious configuration step that would cause this?

Thanks

Kevin


10 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    Notifications are sent by background jobs. If you have a web farm, you probably run background jobs only in one server. Because otherwise, background jobs may be executed per server which causes problems.

    Is that true for your case?

    Did you handle Redis backplane yourself? Is it integrated to SignalR?

  • User Avatar
    0
    devkev2403 created

    Thank you for your reply.

    I will have to read up on ABP back ground jobs.

    For the backplane, I have a Redis installation and I have simply configured ABP to use it. I haven't made any SignalR changes yet.

    private void ConfigureOwinServices(IAppBuilder app)
    {
        app.Properties["host.AppName"] = "Phone";
    
        app.UseAbp();
    
        // configure SignalR to use Redis backplane
        GlobalHost.DependencyResolver.UseRedis(_redisConnString, 6379, "", "PhonePbx");
        app.MapSignalR();
    }
    

    Then, as per documentation on notifications, I create a notification in AppNotifier class

    public async Task IncomingCallAsync(string ddi, string cli)
    {
        await _notificationPublisher.PublishAsync(
            AppNotificationNames.IncomingCall,
            new MessageNotificationData($"New incoming phone call to {ddi} from {cli}"),
            severity: NotificationSeverity.Success
        );
    }
    

    I haven't had to change any client side code as this is already built in to ABP/Metronic.

    Is this the correct approach. I have a web form behind a load balancer. When I raise a notification I want all clients to receive the notification, which means all servers will have to use SIgnalR to push the notification to their clients.

  • User Avatar
    0
    hikalkan created
    Support Team

    You are sending notification to subscribed users for the current tenant. Did you subscribe to notifications for all users?

  • User Avatar
    0
    devkev2403 created

    Yes, all users are subscribed. I think the back plane is working. I am now using my own version of SignalRRealTimeNotifier as I think the issue may be here.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @devkev2403, does your notification depend on a permission ?

  • User Avatar
    0
    devkev2403 created

    I think I have solved this. The problem is a limitation in the OnlineClientManager. The SignalRRealTimeNotifications class that is used to send SignalR message uses the OnlineClientManager to determine who should get the notification and what the SignalR connection id is. However, the OnlineClientManager is only aware of clients connected to the server it is running on, not the entire web farm.

    To fix this I am moving the dictionary used by the OnlineClientManager into Redis. It's not finished but so far so good.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @devkev2403 Thanks for the feedback.

  • User Avatar
    0
    gunpal5 created

    @devkev2403

    Is there any chance you can share the codes for your new OnlineClientManager?

    Regards, Gunpal Jain

  • User Avatar
    0
    devkev2403 created

    Unfortunately the code isn't mine to share as it belongs to my employer, however, let me see what I can do, as we do like to give back to the community when we can.

  • User Avatar
    0
    JeffMH created

    If they don't let you post any code, maybe you could just describe your solution so maybe we can take a stab at it. Then you could maybe review our code :)