【问题标题】:Calling SignalR service from a BackgroundWorker in ABP从 ABP 中的 BackgroundWorker 调用 SignalR 服务
【发布时间】:2018-02-26 02:23:35
【问题描述】:

我有一个 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 总是为空!我应该在哪里初始化它?

【问题讨论】:

    标签: c# asp.net-core signalr backgroundworker aspnetboilerplate


    【解决方案1】:

    注入IHubContext&lt;HitchHub&gt; 而不是IHitchHub

    例如,请参阅 ABP 的 SignalRRealTimeNotifier

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

    【讨论】:

      【解决方案2】:

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

      Call SignalR Core Hub method from Controller

      否则:

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

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

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

      **Hub对象生命周期的背景信息:**

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

      您不会实例化 Hub 类或调用它 服务器上您自己的代码中的方法;为你所做的一切 SignalR 集线器管道。 SignalR 创建集线器的新实例 每次需要处理 Hub 操作时的类,例如当一个 客户端连接、断开连接或对服务器进行方法调用。

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

      如果您想通过自己运行的代码向客户端发送消息 在 Hub 类之外,您不能通过实例化 Hub 类来做到这一点 例如,但您可以通过获取对 SignalR 的引用来实现 Hub 类的上下文对象。有关详细信息,请参阅如何 稍后从 Hub 类外部调用客户端方法和管理组 在这个话题中。

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

      【讨论】:

      • 从 OP 之前的问题来看,他正在使用 ASP.NET Core。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多