Signalr client doesn't get hub messages?

Viewed 121

I'm using .net core 5 with a simple setup:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddSignalR();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    ...

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chathub");
        endpoints.MapControllers();
    });
}

With this simple Hub :

public interface IChatClient
{
    Task SendMessage( string message);
}

public class ChatHub : Hub<IChatClient>
{
    public Task SendMessage(string message)
    {
        return Clients.All.SendMessage(   message);
    }
}

This is my simple controller :

public class WeatherForecastController : ControllerBase
{
    private readonly IHubContext<ChatHub> _hubContext;

    

    public WeatherForecastController(IHubContext<ChatHub> hubContext)
    {
        _hubContext = hubContext;
    }

    [HttpGet]
    public async Task<IActionResult> Get()
    {
        await _hubContext.Clients.All.SendAsync("ReceiveMessage", $"Home page loaded at: {DateTime.Now}");
        return Ok();
    }
}

(For simplicity, whenever the GET HTTP endpoint is invoked, a message should be sent).

The C# console client is :

async Task Main()
{
    var uri = "http://localhost:5000/chatHub";
    await using var connection = new HubConnectionBuilder().WithUrl(uri).Build();

    await connection.StartAsync();
    connection.On<string>("ReceiveMessage", (message) => Console.WriteLine(message));

    
}

Question:

Both apps are working but I do not see any message in the client-side when I'm refreshing the page. I might be missing something here.

1 Answers

Most likely your client (console) application just exists before any message arrives. You have:

await using var connection

Which will dispose connection and the end of the scope, which is the end of the method. connection.On is not a blocking call, it just subscribes to the message. So in the end your connection is immediately disposed and your application exits.

Just add something like Console.ReadKey() at the end, to test it. Or, do not dispose a connection at the end of the scope.

Update: you said you are using LINQPad and Util.keeprunning() method. This doesn't help in this case, because keeprunning() is not a blocking call, it keeps process from exiting yes, until you dispose what is returned by this method, BUT control still leaves your method and that means connection is disposed because of async using var connection = .... You need to remove this and dispose connection explicitly on some condition (like 2 messages received).

Related