2
votes

We have a SignalR application that we built and tested for use on a single web server. The requirements have changed and we need to deploy the application to a webfarm. SignalR supports several backplanes, since the application already uses Sql Server that is what we have implemented. With the introduction of a second web node we ran into an issue with keeping the data that is cached within the Hub synced between the nodes.

Each hub has an internal cache in the form of a DataSet. private static DataSet _cache; The cache gets populated when a client first requests data, and from there any interaction updates the local cache and the sql server, then notifies all connected clients of the changes.

The backplane handles the broadcast messages between the clients but the other node does not receive a message.

Our first thought was that there might be a method that we could wire up that would triggered from the backplane sending a message to a nodes clients, but we have not seen such a thing mentioned in documentation.

Our second thought was to create a .net client within the hub.

private async void ConnectHubProxy()
    {
        IHubProxy EventViewerHubProxy = _hubConnection.CreateHubProxy("EventViewerHub");
        EventViewerHubProxy.On<string>("BroadcastAcknowledgedEvents", EventIDs => UpdateCacheIsAcknowledged(EventIDs));
        EventViewerHubProxy.On<string>("BroadcastDeletedEvents", EventIDs => UpdateCacheIsDeleted(EventIDs));
        ServicePointManager.DefaultConnectionLimit = 10;
        await _hubConnection.Start();
    }

Our questions: How do we keep the cache in sync? Is the first thought possible and we missed it in the documentation? Are there any issues concerns with having a hub connect to itself?

1

1 Answers

1
votes

The recommended way to have "state" in a scaleout scenario is to have a source of persistence. So in your case, if you're looking to have a "global-like" cache one way you can implement that is via a database.

By creating a database all your nodes can write/read from the same source and therefore have a global cache.

The reason why having an in-memory cache is not a good idea is because in a web farm, if nodes go down, they then lose all their in-memory cache. By having persistence, it doesn't matter if a nodes been up for days or has just recovered from a "shutdown" based failure, the persistence layer is always there.