我已阅读有关如何通过Signalr核心集线器从后台服务向客户端发送通知的文档。如何接收来自客户端的后台服务通知?
后台服务只能是单例。
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的另一个实例。
答案 0 :(得分:0)
我们解决此问题的方法是将第三项服务作为单例添加到服务集合中。
以下是完整的示例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);
}
}
答案 1 :(得分:0)
您不需要另一个QueueProcessor实例。客户端可以轻松地从他的代码中调用SetIntervalSpeed。 Documentation with an example.
var connection = new signalR.HubConnectionBuilder().withUrl("/autocommithub").build();
connection.invoke("SetIntervalSpeed", interval)
SignalR提供了一个用于创建服务器到客户端RFC的API。