3
  1. I am are trying to get an instance of a Hub Class to call front-end methods from the backend from a class outside of the Hub class.

  2. I am using IHostLifeTime that has a register function that will be running in the background while the server is running in a while loop.

  3. There will be events in the while loop that will trigger signalR to send a message to the client.

Question: How am I supposed to get access to the hub and send a message to the client inside of my manager class in the ApplicationReady() function?

TestHub.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;

namespace SignalREventHandle
{
    public class TestHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            Console.WriteLine($"user: {user} message:{message}");
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }

    }
}

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using System.Threading;

namespace SignalREventHandle
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

      // This method gets called by the runtime. Use this method to add services to the container.

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

  // This method gets called by the runtime. Use this method to configure the HTTP request //pipeline.

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime, IHubContext<TestHub> hubContext)

        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            lifetime.ApplicationStarted.Register(OnAppStarted);

            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>

            {
                endpoints.MapRazorPages();

                endpoints.MapHub<TestHub>("/testHub");
            });
        }

        public async void OnAppStarted()

        {

            //Get Singleton Instance of Manager and then start the application
            var manager = Manager.Instance;
            manager.ApplicationReady();
        }

    }

}

Manager.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace SignalREventHandle

{
    public class Manager
    {
        private bool _isServerRunning;
 
        /// <summary>

        /// Instance of class to implement Singleton

        /// </summary>

        private static readonly Manager _instance = new();

        /// <summary>

        /// Getter for Class instance

        /// </summary>

        public static Manager Instance

        {
            get => _instance;
        }

 

        public async void ApplicationReady()
        {
            var task = Task.Run(() =>
            {
                _isServerRunning = true;

                while (_isServerRunning)

                {

                   // Want to Send Message to Client with SignalR here

                    Thread.Sleep(10000);
                }

            });

        }

    }
}
tf2redspy
  • 31
  • 1

1 Answers1

1

In ASP.NET 4.x SignalR use GlobalHost to provide access to the IHubContext:

public static async Task SendMessage(string user, string message)
{
    Console.WriteLine($"user: {user} message: {message}");

    // Get an instance of IHubContext from GlobalHost
    var hubContext = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
    await hubContext.Clients.All.SendAsync("ReceiveMessage", user, message);
}

In ASP.NET Core SignalR, you can access an instance of IHubContext from the web host.

Program.cs

public class Program
{
    public static IHost WebHost;
    public static void Main(string[] args)
    {
        WebHost = CreateHostBuilder(args).Build();
        WebHost.Run();
    }
    ...
}

Then:

public static async Task SendMessage(string user, string message)
{
    Console.WriteLine($"user: {user} message: {message}");

    // Get an instance of IHubContext from IHost
    var hubContext = Program.WebHost.Services.GetService(typeof(IHubContext<ChatHub>)) as IHubContext<ChatHub>;
    await hubContext.Clients.All.SendAsync("ReceiveMessage", user, message);
}

Documentation:

Cristian
  • 439
  • 4
  • 11