You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确配置与SignalR NotificationHub交互的服务?依赖注入疑问

问题:SignalR Hub的Clients属性为null,依赖注入配置是否正确?

我正尝试创建一个与名为NotificationHub的SignalR Hub交互的服务,当前配置下Hub中的Clients属性为null。请问这样的依赖注入配置方式是否正确,能否实现服务与Hub的正常交互?

Notification Hub 代码

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

Notification Service 代码

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

问题分析与解决方案

你的依赖注入配置不正确,这就是Clients属性为null的直接原因。SignalR的Hub实例由框架自行管理,不会通过依赖注入容器创建,直接注入INotificationHub会得到一个未完成Hub初始化流程的实例——框架不会为手动创建的Hub实例初始化Clients等核心属性。

正确的做法是注入IHubContext<NotificationHub>,这是SignalR官方提供的、用于在Hub外部与Hub交互的标准方式:

修改后的NotificationService

public class NotificationService : INotificationService
{
    private readonly IHubContext<NotificationHub> _hubContext;

    public NotificationService(IHubContext<NotificationHub> hubContext)
    {
        _hubContext = hubContext;
    }

    public async Task SendNotificationToAll(Notification notification)
    {
        // 直接通过HubContext调用客户端方法
        await _hubContext.Clients.All.SendAsync(notification.Type, notification);
    }
}

调整说明

  1. 无需通过INotificationHub接口注入Hub实例,IHubContext<NotificationHub>已能完成所有与客户端通信的操作。
  2. 若希望保留INotificationHub封装Hub方法,可修改Hub类依赖IHubContext(非必需操作):
public class NotificationHub : Hub, INotificationHub
{
    private readonly IHubContext<NotificationHub> _hubContext;

    public NotificationHub(IHubContext<NotificationHub> hubContext)
    {
        _hubContext = hubContext;
    }

    public async Task Send(Notification notification)
    {
        await _hubContext.Clients.All.SendAsync(notification.Type, notification);
    }
}

但即使这样,外部服务依然应该注入IHubContext<NotificationHub>,而非INotificationHub。

依赖注入注册

确保在Program.cs中正确注册SignalR与服务:

builder.Services.AddSignalR();
builder.Services.AddScoped<INotificationService, NotificationService>();

同时配置Hub的Endpoint:

app.MapHub<NotificationHub>("/notificationHub");

完成上述修改后,服务即可正常与SignalR Hub交互,Clients属性也不会再为null。


内容的提问来源于stack exchange,提问作者Scott

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:33:24