【问题标题】:SignalR Hubs Clients are null when firing eventSignalR Hubs 客户端在触发事件时为空
【发布时间】:2018-05-08 00:12:41
【问题描述】:

我编写了一个通用集线器,但遇到了一些问题,因此为了调试它,我决定像这样进行简单的连接计数:

public class CRUDServiceHubBase<TDTO> : Hub, ICRUDServiceHubBase<TDTO>
{
    public const string CreateEventName = "EntityCreated";
    public const string UpdateEventName = "EntityUpdated";
    public const string DeleteEventName = "EntityDeleted";

    protected int _connectionCount = 0;

    public Task Create(TDTO entityDTO)
    {
        return Clients.All.InvokeAsync(CreateEventName, entityDTO);
    }

    public Task Update(TDTO entityDTO)
    {
        return Clients.All.InvokeAsync(UpdateEventName, entityDTO);
    }

    public Task Delete(object[] id)
    {
        return Clients.All.InvokeAsync(DeleteEventName, id);
    }

    public override Task OnConnectedAsync()
    {
        this._connectionCount++;
        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(Exception exception)
    {
        this._connectionCount--;
        return base.OnDisconnectedAsync(exception);
    }
}

public class MessagesHub : CRUDServiceHubBase<MessageDTO>
{
    public MessagesHub() : base()
    {
    }
}

我正在这样注册这个类:

services.AddTransient<ICRUDServiceHubBase<MessageDTO>, MessagesHub>();

我有一个服务正在使用它,我正在使用它的实现工厂来订阅它的事件:

services.AddTransient<IMessageDTOService>( (c) => {

    var context = c.GetRequiredService<DbContext>();
    var adapter = c.GetRequiredService<IAdaptable<Message, IMessageDTO, MessageDTO>>();
    var validator = c.GetRequiredService<IValidator<Message>>();
    var entityMetadataService = c.GetRequiredService<IEntityMetadataService<Message>>();

    var service = new MessageDTOService(context, adapter, validator, entityMetadataService);
    var hub = c.GetService<ICRUDServiceHubBase<MessageDTO>>();
    this.RegisterHubsCreate(service, hub);

    return service;
});

当我触发事件时,我得到一个空引用:

Microsoft.AspNetCore.SignalR.Hub.Clients.get 返回 null。

我最好的猜测是,因为服务是控制器的依赖项,所以它是在 signalR 可以初始化它的客户端之前创建的?

是否有人对我如何注册我的活动并填充客户端有什么建议?

【问题讨论】:

    标签: c# asp.net-core .net-core dependency-injection inversion-of-control


    【解决方案1】:

    事实证明,当我想调用服务器端时,我需要将 IHubContext 注入到我的集线器中才能访问客户端。

    protected IHubContext<CRUDServiceHubBase<TDTO>> _context;
    
    public CRUDServiceHubBase(IHubContext<CRUDServiceHubBase<TDTO>> context)
    {
        this._context = context;
    }
    
    public Task Create(TDTO entityDTO)
    {
        return this._context.Clients.All.InvokeAsync(CreateEventName, entityDTO);
    }
    

    【讨论】:

    • 当我使用 Clients 时,在 OnConnected 方法中我有有效的计数,Clients 方法已初始化,我可以在 OnConnected 中调用 FE 方法,这意味着 BE 和 FE 已正确连接。后来当我尝试向所有人发送消息时,Clients 为空,我什至尝试使用你描述的上下文,然后我有Clients,但计数为 0,所以什么也没有发生
    • @Serlok 你在尝试推送时是否传入了 IHubContext?
    • 当我在我的服务中注入 IHubContext 时,它正在工作,但是当我将它注入到我的 Hub 时,它就不起作用了,我的想法是将 IHubContext 从我的服务发送到 Hub 方法作为论据
    • @Serlok 我已经有一段时间没有在 SignalR 上工作了,但作为猜测,我认为您不能将 HubContext 注入 Hub,因为 HubContext 依赖于 Hub。 (我可能弄错了,但那是我最好的理论 ATM)
    • 我注射过 - 没有区别
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多