所以对于我的blazor应用程序目前正在生产中。
我确实需要在某些时候发布新版本。我想知道当时是否有人在使用这个应用程序。为此,我可以询问每个人(大约20个同事)是否有人在使用这个应用程序。
我觉得应该有一种更简单的方法来做到这一点。现在我知道blazor应用程序使用SignalR执行服务器和客户端之间的通信,并且当我重新启动docker容器时,所有连接都被重置。所以我觉得应该有一种方法可以从SignalR Hub请求是否有人连接到应用程序,但我还没有找到一种方法。
有没有人知道有什么方法可以检查在x点是否(以及谁)正在使用应用程序?
简单的方法是使用依赖注入。在Blazor服务器上,作用域几乎意味着"一个实例通过连接":
Blazor服务器托管模型支持跨HTTP请求的范围生存期,但不支持跨客户端上加载的组件之间的SignalR连接/电路消息的范围生存期。应用的Razor Pages或MVC部分正常地处理作用域服务,并在页面或视图之间导航或从页面或视图导航到组件时,在每个HTTP请求上重新创建服务。在客户端组件之间导航时,不重构作用域服务,在客户端组件中,与服务器的通信是通过用户电路的SignalR连接进行的,而不是通过HTTP请求。在客户端上的以下组件场景中,由于为用户创建了新的电路,因此重构了作用域服务:
- 用户关闭浏览器窗口。用户打开一个新窗口并导航回应用程序。
- 用户在浏览器窗口中关闭应用程序的一个选项卡。用户打开一个新标签页并导航回应用程序。
- 用户选择浏览器的重载/刷新按钮。
如果您可以接受将终生SignalR连接/电路视为"已连接的用户",则该过程非常简单。我一步一步地解释这个过程:
1 -创建存储连接用户列表的结构
创建类来存储ConnectedUser
数据和ConnectedUserList
:
public class ConnectedUser
{
public string Name { get; set; } = Guid.NewGuid().ToString();
}
public class ConnectedUserList
{
public List<ConnectedUser> Users { get; set; } = new();
}
2 -注入具有正确作用域的类
在program.cs
上注入两个类:ConnectedUser
(作用域)和ConnectedUserList
(单例),它们将包含ConnectedUser
的列表。
// Program.cs
builder.Services.AddScoped<ConnectedUser>();
builder.Services.AddSingleton<ConnectedUserList>();
3 -捕获连接的用户并添加到全局列表
在Shared/MainLayout.razor
上,通过注入两个对象并将ConnectedUser
添加到ConnectedUserList
(在登录过程或事件中,您可以将ConnectedUser.Username
更新为登录的用户名)
@implements IDisposable
@inject ConnectedUser _ConnectedUser
@inject ConnectedUserList _ConnectedUserList
@code {
protected override void OnInitialized()
{
_ConnectedUserList.Add(_ConnectedUser )
}
// Don't forget to remove `ConnectedUser` from
// `ConnectedUserList` on dispose.
public void Dispose()
{
_ConnectedUserList.Remove(_ConnectedUser )
}
4 -显示所有连接的用户
在任何时候你都可以得到ConnectedUserList
并检查列表。例如index.razor
:
@page "/"
@inject ConnectedUser _ConnectedUser
@inject ConnectedUserList _ConnectedUserList
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
@foreach (var user in _ConnectedUserList.Users)
{
<p>@user.Name</p>
}
指出- 为了保持答案简单,我使用
List
结构体来存储连接的用户,但List
不是线程安全的。