我已经阅读了有关如何通过信号器核心集线器从后台服务向客户端发送通知的文档。如何从客户端接收后台服务的通知?
后台服务应该只是一个单身人士。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedService<QueueProcessor>();
services.AddSignalR();
}
public void Configure(IApplicationBuilder app)
{
app.UseSignalR(routes =>
{
routes.MapHub<AutoCommitHub>("/autocommithub");
});
}
}
public class QueueProcessor : BackgroundService
{
private int interval;
public QueueProcessor(IHubContext<AutoCommitHub> hubContext)
{
this.hub = hubContext;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await BeginProcessingOrders();
Thread.Sleep(interval);
}
}
internal async Task BroadcastProcessStarted(string orderNumber)
{
await hub.Clients.All.SendAsync("ReceiveOrderStarted",
orderNumber);
}
internal void SetInterval(int interval)
{
this.interval = interval;
}
}
public class AutoCommitHub : Hub
{
private readonly QueueProcessor queueProcessor;
public AutoCommitHub(QueueProcessor _processor)
{
queueProcessor = _processor;
}
public void SetIntervalSpeed(int interval)
{
queueProcessor.SetInterval(interval);
}
}
我需要能够从客户端调用SetInterval方法。客户端通过集线器连接。我不希望实例化QueueProcessor的另一个实例。
我们解决这个问题的方法是将第三个服务添加到服务集合中作为单例。
这是PoC的完整示例:https://github.com/doming-dev/SignalRBackgroundService
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedService<QueueProcessor>();
services.AddSingleton<HelperService>();
services.AddSignalR();
}
}
HelperService引发后台服务可以锁定的事件。
public class HelperService : IHelperService
{
public event Action OnConnectedClient = delegate { };
public event Action<int> SpeedChangeRequested = delegate { };
public void OnConnected()
{
OnConnectedClient();
}
public void SetSpeed(int interval)
{
SpeedChangeRequested(interval);
}
}
客户端发送消息时的集线器可以调用HelperService上的方法,这反过来将引发后台服务正在处理的事件。
public class MyHub : Hub
{
private readonly IHelperService helperService;
public MyHub(IHelperService service)
{
helperService = service;
}
public override async Task OnConnectedAsync()
{
helperService.OnConnected();
await base.OnConnectedAsync();
}
public void SetSpeed(int interval)
{
helperService.SetSpeed(interval);
}
}
您不需要另一个QueueProcessor实例。客户端可以从代码中轻松调用SetIntervalSpeed。 Documentation with an example.
var connection = new signalR.HubConnectionBuilder().withUrl("/autocommithub").build();
connection.invoke("SetIntervalSpeed", interval)
SignalR提供了用于创建服务器到客户端RFC的API。