Skip to content

Instantly share code, notes, and snippets.

@pmendonca
Created February 24, 2026 11:17
Show Gist options
  • Select an option

  • Save pmendonca/5a0e26ea22a4b0793f6e9e0bdbf1d112 to your computer and use it in GitHub Desktop.

Select an option

Save pmendonca/5a0e26ea22a4b0793f6e9e0bdbf1d112 to your computer and use it in GitHub Desktop.
signalr client
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.Logging;
public interface ISignalRClient
{
Task StartAsync(CancellationToken cancellationToken = default);
Task StopAsync(CancellationToken cancellationToken = default);
Task SendAsync(string method, object?[] args, CancellationToken cancellationToken = default);
Task<T> InvokeAsync<T>(string method, object?[] args, CancellationToken cancellationToken = default);
}
public class SignalRClient : ISignalRClient, IAsyncDisposable
{
private readonly HubConnection _connection;
private readonly ILogger<SignalRClient> _logger;
public SignalRClient(
ILogger<SignalRClient> logger)
{
_logger = logger;
var hubUrl = "https://localhost:5001/chatHub"; // <- mover para config depois
_connection = new HubConnectionBuilder()
.WithUrl(hubUrl)
.WithAutomaticReconnect(new[]
{
TimeSpan.Zero,
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(10),
TimeSpan.FromSeconds(30),
})
.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Information);
})
.Build();
RegisterHandlers();
RegisterLifecycleEvents();
}
private void RegisterHandlers()
{
_connection.On<string, string>("ReceiveMessage", (user, message) =>
{
_logger.LogInformation("[{User}] {Message}", user, message);
});
}
private void RegisterLifecycleEvents()
{
_connection.Reconnecting += error =>
{
_logger.LogWarning("SignalR reconnecting... {Error}", error?.Message);
return Task.CompletedTask;
};
_connection.Reconnected += connectionId =>
{
_logger.LogInformation("SignalR reconnected. ConnectionId={ConnectionId}", connectionId);
return Task.CompletedTask;
};
_connection.Closed += async error =>
{
_logger.LogWarning("SignalR closed. {Error}", error?.Message);
await Task.Delay(2000);
await StartAsync();
};
}
public async Task StartAsync(CancellationToken cancellationToken = default)
{
if (_connection.State == HubConnectionState.Connected)
return;
await _connection.StartAsync(cancellationToken);
_logger.LogInformation("SignalR connected. ConnectionId={ConnectionId}", _connection.ConnectionId);
}
public async Task StopAsync(CancellationToken cancellationToken = default)
{
if (_connection.State == HubConnectionState.Disconnected)
return;
await _connection.StopAsync(cancellationToken);
_logger.LogInformation("SignalR stopped.");
}
public Task SendAsync(string method, object?[] args, CancellationToken cancellationToken = default)
{
return _connection.SendAsync(method, args, cancellationToken);
}
public Task<T> InvokeAsync<T>(string method, object?[] args, CancellationToken cancellationToken = default)
{
return _connection.InvokeAsync<T>(method, args, cancellationToken);
}
public async ValueTask DisposeAsync()
{
await _connection.DisposeAsync();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment