我有一个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!我应该在哪里初始化它?
答案 0 :(得分:2)
注入IHubContext<HitchHub>
而不是IHitchHub
。
例如,请参阅ABP的SignalRRealTimeNotifier。
答案 1 :(得分:0)
如果您使用Asp.net Core,请参阅:
Call SignalR Core Hub method from Controller
否则:
Hub不应由您自己或任何注入框架实例化
您必须使用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 Hubs管道。 SignalR创建Hub的新实例 class每次需要处理一个Hub操作时,例如a 客户端连接,断开连接或对服务器进行方法调用。
由于Hub类的实例是瞬态的,因此您无法使用它们 保持状态从一个方法调用到下一个。每一次 服务器接收来自客户端的方法调用,一个新的实例 Hub类处理消息。通过多重维持状态 连接和方法调用,使用一些其他方法,如a 数据库,或Hub类上的静态变量,或其他类 这不是来自Hub。如果您将数据保留在内存中,请使用 方法如Hub类上的静态变量,数据将是 应用程序域回收时丢失。
如果要根据自己运行的代码向客户端发送消息 在Hub类之外,您无法通过实例化Hub类来实现 例如,你可以通过获取SignalR的引用来实现 Hub类的上下文对象。有关更多信息,请参见如何 稍后调用客户端方法并从Hub类外部管理组 在这个主题中。