How do I send messages from server to client using SignalR Hubs

In case you come across this question many years after it was asked, and you happen to use .NET 5.0 (or similar), the following may be useful as you might be using a framework that no longer offers the class GlobalHost.

.NET 5.0 (and similar) make heavy use of dependency injection (DI) and it's not a surprise it is used here as well. The following sample code shows how to do this. It doesn't use the class GlobalHost.

Given the ChatHub class as follows:

   public class ChatHub : Hub
   {
      public async Task SendMessage(string user, string message)
      {
         await Clients.All.SendAsync("ReceiveMessage", user, message).ConfigureAwait(false);
      }
   }

in class Startup add a line as indicated in the following code snippet:

   public class Startup
   {
      // other code omitted for brevity

      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
      {
         // other code omitted for brevity

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

         // other code omitted for brevity
      }
   }

Then in a controller where you want to send messages to SignalR message, add the ChatHub as a dependency. The following example demonstrates how to do that for constructor injection:

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

      public WeatherForecastController(
         IHubContext<ChatHub> hubContext, // <============ add this ==========
         ILogger<WeatherForecastController> logger)
      {
         _hubContext = hubContext;
         _logger = logger;
      }
      
      [HttpGet]
      public virtual async Task<IEnumerable<WeatherForecastModel>> Get()
      {
         var rng = new Random();
         WeatherForecastModel[] weatherForecastModels = Enumerable.Range(1, 5).Select(index => new WeatherForecastModel
         {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)],
         }).ToArray();

         // Notify connected SignalR clients with some data:
         await _hubContext.Clients.All.SendAsync("ReceiveMessage", "the weatherman", $" The temperature will be {weatherForecastModels[0].TemperatureC}").ConfigureAwait(false);

         return weatherForecastModels;
      }

      // other code omitted for brevity
   }

This example also shows how to then send messages in the Get() method by using await _hubContext.Clients.All.SendAsync( ... )

For more information see Microsoft's documentation.


I think it should be

 void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<Chat>();
        context.Clients.All.addMessage("Hello");      
    }

instead. With Send you are calling the method used by the client to call the server...