Blazor Server自定义SignalR Hub配置URL未被使用的问题
问题描述
在.NET 9中创建默认Blazor Web应用项目,添加了用于客户端间发送通知的SignalR Hub。当某个会话递增/counter页面数值时,所有会话都会收到通知并更新显示,功能完全正常,但浏览器开发者工具中看不到配置的Hub URL(/counter-notifications)对应的连接,只有指向/_blazor的标准Blazor Server WebSocket连接。是否默认Blazor WebSocket连接被复用给自定义SignalR了?
相关代码
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);
浏览器连接截图

解答
没错,你的自定义SignalR Hub确实复用了Blazor Server默认的/_blazor WebSocket连接,这是.NET 8及以后版本Blazor Server的默认行为——SignalR Hub共享连接复用。
核心原因
- 自动复用机制:Blazor Server启动时会创建主SignalR连接(
/_blazor)用于组件交互和渲染更新。在.NET 8+中,所有同域的SignalR Hub都会自动复用这个已建立的WebSocket连接,无需创建新连接。 - 性能优化考量:这种设计减少了浏览器的连接数开销,避免多WebSocket连接带来的资源消耗,同时简化了连接的生命周期管理。
验证方法
- 查看
CounterHub的OnConnectedAsync日志:页面加载时会打印新的ConnectionId,但浏览器仅显示一个/_blazor连接,说明Hub已通过复用连接完成注册。 - 开启SignalR客户端日志:在
HubConnectionBuilder中添加ConfigureLogging(logging => logging.AddConsole()),可以看到连接复用的详细日志。
如何禁用连接复用(可选)
如果确实需要独立的WebSocket连接,可以在创建HubConnection时显式禁用复用:
_hubConnection = new HubConnectionBuilder() .WithUrl(NavigationManager.ToAbsoluteUri(CounterHub.HubUrl), options => { // 禁用自动重连(可选,根据需求调整) options.DisableAutomaticReconnect(); // 关键:添加自定义请求头告知服务器不复用连接 options.Headers.Add("X-SignalR-No-Reuse", "true"); }) .Build();
注意:除非有特殊业务需求,否则不建议禁用,会失去连接复用带来的性能优势。
内容的提问来源于stack exchange,提问作者orderlyfashion
相关产品推荐
相关产品推荐

