You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server复刻SignalR聊天应用时遇Connection Id required错误

Blazor Server SignalR 聊天应用:"Connection Id required" 错误解决

问题描述

复刻基于Blazor WebAssembly的SignalR聊天应用时改用Blazor Server App开发,点击聊天标签页时浏览器提示**"Connection Id required"**错误。

我的代码实现

Razor组件 (/room1)

@page "/room1"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IDisposable

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection hubConnection;
    private List<string> messages = new List<string>();
    private string userInput;
    private string messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    Task Send() =>
        hubConnection.SendAsync("SendMessage", userInput, messageInput);

    public bool IsConnected => 
        hubConnection?.State == HubConnectionState.Connected;

    public void Dispose()
    {
        _ = hubConnection?.DisposeAsync();
    }
}

Chat Hub类

using Microsoft.AspNetCore.SignalR;

namespace ChatBlazorApp.Server.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

Startup.cs类

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Linq;
using ChatBlazorApp.Server.Hubs;

namespace ChatBlazorApp.Server
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSignalR();
            services.AddControllersWithViews();
            services.AddRazorPages();
            services.AddResponseCompression(opts =>
            {
                opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
                    new[] { "application/octet-stream" });
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseResponseCompression();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseWebAssemblyDebugging();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseBlazorFrameworkFiles();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
                endpoints.MapControllers();
                endpoints.MapHub<ChatHub>("/chathub");
                endpoints.MapFallbackToFile("index.html");
            });
        }
    }
}

错误原因及修复方案

核心问题

Blazor Server本身依赖一个内置的SignalR连接实现组件实时交互,自定义SignalR Client连接未做特殊配置时,会与内置连接产生冲突,触发"Connection Id required"错误。

具体修复步骤

  1. 配置自定义连接跳过协商并指定WebSocket传输
    修改OnInitializedAsync中的连接构建逻辑,避免与内置连接的协商机制冲突:

    hubConnection = new HubConnectionBuilder()
        .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"), options =>
        {
            options.SkipNegotiation = true;
            options.Transports = HttpTransportType.WebSockets;
        })
        .Build();
    
  2. 移除WebAssembly专属调试中间件
    在Startup.cs的Configure方法中删除app.UseWebAssemblyDebugging();,该中间件仅适用于Blazor WebAssembly应用,Blazor Server使用会干扰连接逻辑。

  3. 修正Blazor Server的Fallback路由
    将endpoints.MapFallbackToFile("index.html");改为endpoints.MapFallbackToPage("/_Host");,这是Blazor Server应用的正确 fallback 配置。

  4. 优化连接状态检查逻辑
    原IsConnected字段初始化时hubConnection尚未创建,改为属性形式确保实时获取连接状态:

    public bool IsConnected => hubConnection?.State == HubConnectionState.Connected;
    
  5. 添加连接异常处理(可选)
    在OnInitializedAsync中加入try-catch块,避免连接失败导致组件崩溃:

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"), options =>
            {
                options.SkipNegotiation = true;
                options.Transports = HttpTransportType.WebSockets;
            })
            .Build();
    
        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });
    
        try
        {
            await hubConnection.StartAsync();
        }
        catch (Exception ex)
        {
            messages.Add($"连接失败: {ex.Message}");
            StateHasChanged();
        }
    }
    

内容的提问来源于stack exchange,提问作者Rod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 22:40:32