【问题标题】:How do I push data from hub to client every second using SignalR如何使用 SignalR 每秒将数据从集线器推送到客户端
【发布时间】:2019-07-26 02:40:56
【问题描述】:

致力于构建 signalR 集线器,我能够从集线器获取数据到客户端,但我不确定如何每 1 秒推送一次。

我不确定在存在getApps 方法的控制器或集线器中的何处设置计时器?

枢纽:

public class nphub : Hub
{
    public readonly sbController _sbcontroller;

    public nphub(sbController sbcontroller)
    {
        _sbcontroller = sbcontroller;
    }

    public async Task NotifyConnection()
    {
        IActionResult result = await _sbcontroller.getApps();
        await Clients.All.SendAsync("TestBrodcasting", result);
    }
}

在控制器中:

public async Task<IActionResult> getApps()
{
    // var request = new HttpRequestMessage(HttpMethod.Get, "apps");
    // var response = await _client_NP.SendAsync(request);
    // var json = await response.Content.ReadAsStringAsync();

    return Ok($"Testing a Basic HUB at {DateTime.Now.ToLocalTime()}");
}

客户:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/nphub").build();

connection.start().then(function () {
    TestConnection();
}).catch(function (err) {
    return console.error(err.toString());
});

function TestConnection() {
    connection.invoke("NotifyConnection").catch(function (err) {
        return console.error(err.toString());
    });
}

connection.on("TestBrodcasting", function (time) {
    document.getElementById('broadcastDiv').innerHTML = time.value;
    document.getElementById('broadcastDiv').style.display = "block";
});

仅出于测试目的以查看实时更改,我正在尝试返回时间。我可以在客户端上看到时间,但它没有改变。

【问题讨论】:

  • 为什么要每秒推送数据? SignalR 的重点是您不需要这样做。你只需要在数据发生变化时推送数据。
  • 这取决于数据是什么以及您如何检查它。例如,如果数据是数据库中的表,您可以使用SqlDependency。或者它可能是消息被添加到队列的结果。或用户发布聊天消息。
  • 我该怎么做?在这段时间内不断变化,我仍然无法在屏幕上看到它
  • 我正在处理需要从 API 中提取数据的仪表板,在这种情况下如何获得连续的数据流
  • 理想情况下,API 应该有一些机制来订阅更改,以便它可以向您推送更新,而不是您必须轮询。假设它没有,那么您需要编写一些代码来访问该 API,确定自上次轮询尝试以来数据是否已更改,从而决定是否需要通过集线器将更新推送到连接的客户端。

标签: asp.net-core .net-core asp.net-core-mvc signalr signalr-hub


【解决方案1】:

您需要使用托管服务,如docs 中所述。添加一个类:

internal class SignalRTimedHostedService : IHostedService, IDisposable
{
    private readonly IHubContext<nphub> _hub;
    private readonly ILogger _logger;
    private Timer _timer;

    public SignalRTimedHostedService(IHubContext<nphub> hub, ILogger<SignalRTimedHostedService> logger)
    {
        _hub = hub;
        _logger = logger;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is starting.");

        _timer = new Timer(DoWork, null, TimeSpan.Zero, 
            TimeSpan.FromSeconds(1));

        return Task.CompletedTask;
    }

    private void DoWork(object state)
    {
        _logger.LogInformation("Timed Background Service is working.");
        // send message using _hub
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is stopping.");

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

注意:托管服务存在于单例范围内。不过,您可以直接注入 IHubContext&lt;T&gt;,因为它也在单例范围内。

然后在ConfigureServices:

services.AddHostedService<SignalRTimedHostedService>();

【讨论】:

  • 绝妙的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-13
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多