ASP.NET Core 3.1-从托管服务中,检查是否加载了客户端(索引)页



我有一个使用VS2019 Razor Pages模板的简单单页web应用程序。托管服务将通过SignalR向页面发送数据。是否可以检查客户端页面(索引页面(是否已加载,因为如果未加载,则托管服务将暂停发送数据?当从VS2019运行时,页面当然会自动打开;dotnet运行";我需要知道用户是否已将页面加载到浏览器中,例如,他们可能会在服务启动后将其关闭。

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;
}
}
}

实现简单的SignalR连接计数器

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;
}
}
}
}

在Startup类的ConfigureServices中,将SignalRConnectionList添加为singleton

services.AddSingleton<SignalRConnectionList>();

覆盖集线器类中的OnConnectedAsync和OnDisconnectedAsync方法

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);
}

现在在IHostedService中,您可以使用在之上实现的连接计数器

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);
}
}
}

通常,您无法回答是否在web服务器中加载了索引页的问题。服务器只是将内容提供给客户端,客户端可以对这些内容为所欲为,而无需向服务器通知详细信息。

但是,如果您有从客户端到服务器的SignalR连接,则每个连接都在服务器上具有状态。我认为这就是你需要用来解决问题的方法。

您可以覆盖SignalRHubOnConnectedAsyncOnDisconnectedAsync方法来跟踪连接。然后可以与您的后台服务共享这些信息,后台服务使用IHubContext向所有客户端发送数据(但仅当存在任何客户端时(。

最新更新