在 .NET 9 中,我创建了一个默认的 Blazor Web 应用程序项目,并添加了一个 SignalR 中心,用于在客户端之间发送通知。
当一个会话增加
/counter
的值时,所有会话都会收到此通知并更新其显示的值。这一切都有效。
我不明白的是,为什么在浏览器开发者工具中,没有连接到配置的 Hub URL。只有标准 Blazor 服务器 websocket 到
/_blazor
。
Counter.razor
的隐藏代码更新如下:
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private HubConnection _hubConnection;
public async ValueTask DisposeAsync()
{
await _hubConnection.DisposeAsync();
}
protected override async Task OnInitializedAsync()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl(NavigationManager.ToAbsoluteUri(CounterHub.HubUrl))
.Build();
_hubConnection.On<CounterNotification>(CounterHub.CounterUpdatedMethod, HandleCounterUpdated);
await _hubConnection.StartAsync();
}
private void HandleCounterUpdated(CounterNotification notification)
{
currentCount = notification.Counter;
InvokeAsync(StateHasChanged);
}
private async Task IncrementCount()
{
await CounterHubContext.Clients.All.SendAsync(CounterHub.CounterUpdatedMethod, new CounterNotification(currentCount + 1));
}
}
CounterHub.cs
是这样实现的:
public class CounterHub : Hub
{
public const string HubUrl = "/counter-notifications";
public const string CounterUpdatedMethod = "CounterUpdated";
public override Task OnConnectedAsync()
{
Console.WriteLine("{0} connected", Context.ConnectionId);
return base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception? e)
{
Console.WriteLine("{0} disconnected", Context.ConnectionId);
await base.OnDisconnectedAsync(e);
}
}
CounterNotification.cs
看起来像这样:
public record CounterNotification(int Counter)
{
public CounterNotification() : this(0) { }
}
这一切都与
Program.cs
中添加的这些行相关联:
builder.Services.AddSignalR();
builder.Services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
["application/octet-stream"]);
});
app.UseResponseCompression();
app.MapHub<CounterHub>(CounterHub.HubUrl);
有了这个,我希望看到一个 websocket 打开到
/counter-notifications
。但什么也没有。这是怎么回事?默认 Blazor Websocket 连接是否重用于自定义 SignalR?
有了这个,我希望看到一个 websocket 打开 /抗辩通知。但什么也没有。发生什么事了?
您看不到连接只是因为客户端是 blazor 应用程序而不是浏览器,浏览器没有直接连接到
/counter-notifications
public class CounterHub : Hub
{
public const string HubUrl = "/counter-notifications";
public const string CounterUpdatedMethod = "CounterUpdated";
public override Task OnConnectedAsync()
{
Console.WriteLine("/counter-notifications-{0} connected", Context.ConnectionId);
return base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception? e)
{
Console.WriteLine("{0} disconnected", Context.ConnectionId);
await base.OnDisconnectedAsync(e);
}
}