My .NET BackgroundService application have multple workers and all of them connects to the same SignalR Hub. Each worker gets a unique ConnectionId which will not work in my case.
How, if possible, can I share the HubConnection between all of the workers to prevent different ConnectionIds?
I found a solution that solves my issue.
I've created a HubService which every worker dependency inject and then calls EnsureConnectionEstablished()
to make sure the connection is established.
public class HubService
{
private readonly ILogger<SystemHealthWorker> _logger;
private readonly ConfigurationService _config;
private HubConnection _connection;
public HubService(ILogger<SystemHealthWorker> logger, ConfigurationService configService)
{
_logger = logger;
_config = configService;
}
public async Task<bool> EnsureConnectionEstablished()
{
_logger.LogDebug("Ensures that the hub connection is established.");
if (_connection == null || _connection.State == HubConnectionState.Disconnected)
{
_logger.LogDebug("Hub connection is not established.");
var config = await _config.GetConfiguration();
if (config == null || string.IsNullOrEmpty(config.ServerAddress?.ToString()))
{
throw new Exception("Invalid config. Hub connection will not be established.");
}
else if (string.IsNullOrWhiteSpace(config.AccessToken))
{
throw new Exception("Invalid access token.");
}
var hubUrl = new Uri(config.ServerAddress);
_logger.LogInformation($"Connecting to hub ({hubUrl})");
_logger.LogDebug("Building hub connection.");
_connection = new HubConnectionBuilder()
.WithUrl(hubUrl, options => { options.AccessTokenProvider = () => Task.FromResult(config.AccessToken); })
.WithAutomaticReconnect(new[] { TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(120) })
.Build();
_connection.Reconnecting += OnReconnecting;
_connection.Reconnecting += OnReconnected;
_connection.Closed += OnClosed;
await _connection.StartAsync();
_logger.LogInformation($"Connected to hub with id {_connection.ConnectionId}.");
}
return _connection?.State == HubConnectionState.Connected;
}
}