ASP.NET Core 3.1 - From a Hosted Service, check if client (Index) page is loaded

扶醉桌前 提交于 2021-01-29 05:50:46

问题


I have a simple 1-page web app using the VS2019 Razor Pages template. The hosted service will send data to the page via SignalR. Is it possible to check if the client page (Index page) is loaded because if not then the hosted service will pause sending data? When running from VS2019 the page of course opens automatically but running from "dotnet run" I need to know if the user has loaded the page into the browser e.g. they might shut it down after the service has started.

namespace TestProject
{
    public class TestService : IHostedService
    {
        public TestService(ILogger<TestService> logger)
        {
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            // HERE - check if index page is loaded - how??

            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

    }
}

回答1:


Implement simple SignalR connection counter

public class SignalRConnectionList
{
    private readonly object _sync = new object();
    private readonly List<string> _items = new List<string>();

    public void Remove(string connectionId)
    {
        lock (_sync)
        {
            _items.Remove(connectionId);
        }
    }

    public void Add(string connectionId)
    {
        lock (_sync)
        {
            _items.Add(connectionId);
        }
    }

    public int Count
    {
        get
        {
            lock (_sync)
            {
                return _items.Count;
            }
        }
    }
}

In ConfigureServices of Startup class add SignalRConnectionList as singleton

services.AddSingleton<SignalRConnectionList>();

Override OnConnectedAsync and OnDisconnectedAsync methods in Hub class

public class ChatHub: Hub
{
    public ChatHub(SignalRConnectionList connectionList)
    {
        ConnectionList = connectionList;
    }

    private SignalRConnectionList ConnectionList { get; }

    public override Task OnConnectedAsync()
    {
        ConnectionList.Add(Context.ConnectionId);
        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(Exception exception)
    {
        ConnectionList.Remove(Context.ConnectionId);
        return base.OnDisconnectedAsync(exception);
    }

Now in IHostedService you can use connection counter implemented above

public class SimpleService : BackgroundService
{
    public SimpleService(
        ILogger<SimpleService> logger,
        IHubContext<ChatHub> hubContext,
        SignalRConnectionList connectionList)
    {
        Logger = logger;
        HubContext = hubContext;
        ConnectionList = connectionList;
    }

    private SignalRConnectionList ConnectionList { get; }

    protected override async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            await Task.Delay(1000, cancellationToken);
            if (ConnectionList.Count > 0)
            {
                await HubContext.Clients.All.SendAsync("ReceiveMessage", "system", "ping " + DateTime.Now, cancellationToken);
            }
        }
    }



回答2:


In general you cannot answer the question check if index page is loaded in a web server. The server just serves content to clients that can do whatever they like with that content without the server being informed about the details.

However, if you have a SignalR connection from the client to the server you have state on the server for each connection. I think that is what you need to use to solve your problem.

You can override the OnConnectedAsync and OnDisconnectedAsync methods of your SignalR Hub to keep track of connections. This information can then be shared with your background service that uses IHubContext to send data to all clients (but only if there are any clients).



来源:https://stackoverflow.com/questions/63717414/asp-net-core-3-1-from-a-hosted-service-check-if-client-index-page-is-loaded

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!