如何正确设置与 SignalR Hub 交互的服务

问题描述 投票:0回答:1
我正在尝试创建一个与 SignalR Hub 交互的服务,我称之为

NotificationHub

。我已经使用此方法标记了 
Clients
 为空的位置。这是使用集线器设置依赖项注入以便可以与服务一起使用的正确方法吗?

通知中心

public interface INotificationHub { Task Send(Notification notification); }
public class NotificationHub : Hub, INotificationHub
    {
        public async Task Send(Notification notification)
        {
            //Clients is null here
            await Clients.All.SendAsync(notification.Type, notification);
        }
    }
通知服务

public interface INotificationService { Task SendNotificationToAll(Notification notification); }
public class NotificationService : INotificationService
    {
        private readonly INotificationHub _hubContext;

        public NotificationService(INotificationHub hubContext)
        {
            _hubContext = hubContext;
        }

        public async Task SendNotificationToAll(Notification notification)
        {
            await _hubContext.Send(...);
        }
    }
尝试从控制器调用:

public class SomeController : Controller { private readonly INotificationService _notificationService; public SomeController (..., INotificationService notificationService) { _notificationService = notificationService; } [HttpPost, Route("notification")] public async Task<IActionResult> Notification() { _notificationService.SendNotificationToAll(notification1); } }
    
c# dependency-injection signalr asp.net-core-signalr
1个回答
0
投票
先检查一下测试结果,通常我们会像下面的步骤来实现这个要求。

项目结构

我的示例项目中没有 INotificationHub。

NotificationHub.cs

using SignalrSample.Models; using Microsoft.AspNetCore.SignalR; namespace SignalrSample { public class NotificationHub : Hub { public async Task SendMessage(Notification notification) { await Clients.All.SendAsync("ReceiveNotification", notification.Type, notification); } } }

INotificationService.cs

using SignalrSample.Models; namespace SignalrSample.IService { public interface INotificationService { Task SendNotificationToAll(Notification notification); } }

NotificationService.cs

using Microsoft.AspNetCore.SignalR; using SignalrSample.IService; using SignalrSample.Models; namespace SignalrSample.Service { public class NotificationService : INotificationService { private readonly IHubContext<NotificationHub> _hubContext; public NotificationService(IHubContext<NotificationHub> hubContext) { _hubContext = hubContext; } public async Task SendNotificationToAll(Notification notification) { await _hubContext.Clients.All.SendAsync("ReceiveNotification", notification.Type, notification); } } }

模型-Notification.cs

namespace SignalrSample.Models { public class Notification { public string? Type { get; set; } public string? Message { get; set; } } }

HomeController 内部的测试方法

[HttpPost, Route("notification")] public async Task<IActionResult> Notification([FromBody] Notification notification) { await _notificationService.SendNotificationToAll(notification); return Ok(); }

程序.cs

using SignalrSample.IService; using SignalrSample.Service; namespace SignalrSample { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddSignalR(); builder.Services.AddTransient<INotificationService, NotificationService>(); var app = builder.Build(); ... app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.MapHub<NotificationHub>("/notificationHub"); app.Run(); } } }
    
© www.soinside.com 2019 - 2024. All rights reserved.