I don't know why the _hub.Clients.All.SendSync not works in your side, it should be work. But you also could try to define the function inside the Hub class and invoke it in your controller. Here is the sample, I have tested it.
And you want server send the message to clients automaticly, we could use Background service. Here is the sample. You can modify it according your needs. For more details, you can check my previous answer.
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using SignalRMiddleawre.Hubs;
namespace BackgroundService
{
public class TimedHostedService : IHostedService, IDisposable
{
private int executionCount = 0;
private readonly ILogger<TimedHostedService> _logger;
private readonly IHubContext<MainHub> _hubcontext;
private Timer? _timer = null;
public TimedHostedService(IHubContext<MainHub> hubcontext, ILogger<TimedHostedService> logger)
{
_hubcontext = hubcontext;
_logger = logger;
}
public Task StartAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Timed Hosted Service running.");
_hubcontext.Clients.All.SendAsync("Chat_ReceiveMessage", "[System - Background Service ]", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + "Timed Hosted Service running.");
_timer = new Timer(DoWork, null, TimeSpan.Zero,
TimeSpan.FromSeconds(3));
return Task.CompletedTask;
}
private void DoWork(object? state)
{
var count = Interlocked.Increment(ref executionCount);
_logger.LogInformation(
"Timed Hosted Service is working. Count: {Count}", count);
_hubcontext.Clients.All.SendAsync("Chat_ReceiveMessage", "[System - Background Service ]", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + "DoSomethingAsync method triggered. Count: "+count+"");
}
public Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Timed Hosted Service is stopping.");
_hubcontext.Clients.All.SendAsync("Chat_ReceiveMessage", "[System - Background Service ]", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + "Timed Hosted Service is stopping.");
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
}
}