SignalR Core集线器与BackgroundService .NET Core交互

时间:2019-04-18 20:33:45

标签: .net signalr core background-service

我已阅读有关如何通过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的另一个实例。

2 个答案:

答案 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。