【问题标题】:Calling SignalR functions outside of Hub Class在 Hub 类之外调用 SignalR 函数
【发布时间】:2021-10-29 18:37:05
【问题描述】:
  1. 我正在尝试获取 Hub 类的实例,以从 Hub 类之外的类的后端调用前端方法。

  2. 我正在使用具有注册功能的 IHostLifeTime,该功能将在服务器以 while 循环运行时在后台运行。

  3. while循环中会有事件触发signalR向客户端发送消息。

问题:我应该如何访问集线器并向 ApplicationReady() 函数中的管理器类内部的客户端发送消息?

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);
                }

            });

        }

    }
}

【问题讨论】:

    标签: dependency-injection signalr signalr-hub asp.net-core-signalr


    【解决方案1】:

    ASP.NET 4.x SignalR 中使用 GlobalHost 提供对 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);
    }
    

    ASP.NET Core SignalR 中,您可以从 Web 主机访问 IHubContext 的实例。

    程序.cs

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

    然后:

    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);
    }
    

    文档:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-04
      • 1970-01-01
      相关资源
      最近更新 更多