是否可以使用SignalR进行后台任务

时间:2016-09-08 11:31:11

标签: signalr

我正在使用Microsoft SignalR将通知推送到浏览器。这些通知由其他浏览器的操作触发。我想做一个后台任务,有时发送通知。例如,在12:45:21我想向所有连接的用户发出通知,即使他们什么都不做。有可能吗?

2 个答案:

答案 0 :(得分:3)

SignalR不能让你运行后台任务,但如果你正在运行后台任务,那么使用你的SignalR中心来调用客户端方法并发送任何所需的通知都没有什么可以阻止你的任务。

要启动和控制后台任务,Hangfire是一个灵活的库,可以提供帮助。

编辑添加:由于您已经明确表示要在Windows服务中执行此操作,因此另一个帮助构建和部署服务的着名库是TopShelf

编辑添加:另外,我从您的评论中收集到您正试图了解如何从后台任务访问中心对象?有很多方法可以做到这一点,但为了提高程序的可测试性和可维护性,我建议使用IoC(Inversion of Control)容器,并注入必要的引用 - 本教程:Dependency Injection in SignalR使用了演练Ninject库。{该演练面向asp.net托管,但您找到的链接应该有助于适应Windows服务。

答案 1 :(得分:2)

如果您正在使用asp.net core 2.1,现在可以使用BackgroundService / IHostedService

https://github.com/davidfowl/UT3/blob/fb12e182d42d2a5a902c1979ea0e91b66fe60607/UTT/Scavenger.cs#L9-L40 (下面的内容)

public class Scavenger : BackgroundService
    {
        private readonly IHubContext<UTTHub> _hubContext;
        private readonly ILogger<Scavenger> _logger;
        public Scavenger(IHubContext<UTTHub> hubContext, ILogger<Scavenger> logger)
        {
            _hubContext = hubContext;
            _logger = logger;
        }
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                // Mark games that haven't played in a while as completed
                var changed = Game.MarkExpiredGames();

                // Mark completed games as removed
                var removed = Game.RemoveCompletedGames();

                if (removed > 0)
                {
                    _logger.LogInformation("Removed {GameCount} games.", removed);
                }

                if (removed > 0 || changed)
                {
                    await _hubContext.Clients.All.SendAsync("GameUpdated", Game.GetGames());
                }

                await Task.Delay(5000);
            }
        }
    }
}

也看到这个 https://github.com/aspnet/Docs/issues/8925