繁体   English   中英

从ABP中的BackgroundWorker调用SignalR服务

[英]Calling SignalR service from a BackgroundWorker in ABP

我有一个BackgroundWorker,它应该以5秒的间隔向所有在线客户端广播一些内容:

DeactivationBackgroundWorker:

public class DeactivationBackgroundWorker : PeriodicBackgroundWorkerBase, ISingletonDependency
{
    private readonly IRepository<HitchRequest, long> _hitchRequestRepository;
    private readonly IHitchHub _hitchHub;

    public DeactivationBackgroundWorker(AbpTimer timer,
                                        IRepository<HitchRequest, long> hitchRequestRepository,
                                        IHitchHub hitchHub) : base(timer)
    {
        _hitchRequestRepository = hitchRequestRepository;
        Timer.Period = 5000;
        _hitchHub = hitchHub;
    }

    protected override async void DoWork()
    {
        await broadcastHitchRequestsAsync();
    }

    [UnitOfWork]
    private async Task broadcastHitchRequestsAsync() {
        var activeHitchRequests = _hitchRequestRepository.GetAllList(p => p.IsActive);

        foreach (var hitchRequest in activeHitchRequests)
        {
            await _hitchHub.RequestHitch(hitchRequest.Id);
        }

    }
}

IHitchHub:

public interface IHitchHub: ITransientDependency
{
    Task RequestHitch(long hitchId);
}

HitchHub:

public class HitchHub : AbpCommonHub, IHitchHub
{
    private readonly IOnlineClientManager _onlineClientManager;

    public HitchHub(IOnlineClientManager onlineClientManager, IClientInfoProvider clientInfoProvider): base(onlineClientManager, clientInfoProvider)
    {
        _onlineClientManager = onlineClientManager;
    }

    public async Task RequestHitch(long hitchId)
    {
        var onlineClients = _onlineClientManager.GetAllClients();
        foreach (var onlineClient in onlineClients) {

            var signalRClient = Clients.Client(onlineClient.ConnectionId);

            await signalRClient.SendAsync("receiveHitch", hitchId);
        }
    }
}

我不知道为什么HitchHub类中的Clients总是为null! 我应该在哪里初始化它?

注入IHubContext<HitchHub>而不是IHitchHub

例如,请参阅ABP的SignalRRealTimeNotifier

相关问题: https : //github.com/aspnet/SignalR/issues/182

如果您使用Asp.net Core,请参阅:

从Controller调用SignalR Core Hub方法

除此以外:

集线器不应由您自己或任何注入框架实例化

您必须使用ConnectionManager。 对于您的代码,您应该使用:

GlobalHost.ConnectionManager.GetHubContext<HitchHub>().RequestHitch(hitchRequest.Id);

**有关集线器对象生存期的背景信息:**

https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server

您无需实例化Hub类或从服务器上自己的代码中调用其方法。 SignalR Hubs管道为您完成了所有这些工作。 SignalR每当需要处理Hub操作时(例如客户端连接,断开连接或对服务器进行方法调用时),都会创建一个新的Hub类实例。

因为Hub类的实例是瞬态的,所以您不能使用它们来维护从一个方法调用到下一个方法调用的状态。 每次服务器从客户端收到方法调用时,您的Hub类的新实例都会处理该消息。 要通过多个连接和方法调用维护状态,请使用其他一些方法,例如数据库,Hub类上的静态变量,或者不是从Hub派生的其他类。 如果使用Hub类上的静态变量之类的方法将数据保留在内存中,则当应用程序域回收时,数据将丢失。

如果要从在Hub类之外运行的自己的代码向客户端发送消息,则无法通过实例化Hub类实例来实现,但是可以通过获取Hub类的SignalR上下文对象的引用来实现。 有关更多信息,请参见本主题后面的如何从Hub类外部调用客户端方法和管理组。

另请参阅: https : //docs.microsoft.com/zh-cn/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server#callfromoutsidehub

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM