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

.NET Core SignalR C#客户端HubConnection.On方法失效问题

SignalR客户端无法接收消息问题

问题说明

我使用.NET Core Web API作为SignalR服务端、控制台应用作为客户端,当前遇到的问题是:客户端能成功调用服务端Hub的SendMessage方法,但通过connection.On<string>("ReceiveMessage")注册的回调未触发,控制台无法输出预期的消息内容。

服务端代码

Startup.cs

public void ConfigureServices(IServiceCollection services)
{

    services.AddControllers();
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "SignalR", Version = "v1" });
    });
    //SignalR服务注册
    services.AddSignalR();
    services.AddCors(c =>
    {
        c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
    });
}

// 运行时调用此方法,用于配置HTTP请求管道
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseSwagger();
        app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "SignalR v1"));
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();

    app.UseCors(o=>o.AllowAnyOrigin());

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        //映射ChatHub的端点
        endpoints.MapHub<ChatHub>("/chathub");
    });
}  

ChatHub类

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

客户端控制台代码

static async Task Main(string[] args)
{
    try
    {
        HubConnection connection = new HubConnectionBuilder().WithUrl("https://localhost:44340/chathub").WithAutomaticReconnect().Build();

        await connection.StartAsync();

        if(connection.State == HubConnectionState.Connected)
        {
            Console.WriteLine("Connected ... Please type message now");
            var message = "Hey";
            //已成功调用ChatHub中的SendMessage方法
            await connection.InvokeAsync("SendMessage", message);
            Console.WriteLine(connection.ConnectionId);
            /*
             Connection.On方法未生效,无法在控制台输出内容。
             我预期控制台会输出结果Hey。
             */
            connection.On<string>("ReceiveMessage", m =>
            {
                Console.WriteLine(m);
            });
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

预期与实际输出

  • 预期输出:
    Connected ... Please type message now
    [ConnectionId]
    Hey
    
  • 实际输出:
    Connected ... Please type message now
    [ConnectionId]
    

解决办法

问题根源在于代码执行顺序:你先调用了SendMessage方法,之后才注册ReceiveMessage的回调。当服务端推送消息时,客户端还未完成回调注册,因此无法触发处理逻辑。

调整代码顺序,先注册回调,再调用SendMessage方法:

static async Task Main(string[] args)
{
    try
    {
        HubConnection connection = new HubConnectionBuilder().WithUrl("https://localhost:44340/chathub").WithAutomaticReconnect().Build();

        // 提前注册ReceiveMessage回调
        connection.On<string>("ReceiveMessage", m =>
        {
            Console.WriteLine(m);
        });

        await connection.StartAsync();

        if(connection.State == HubConnectionState.Connected)
        {
            Console.WriteLine("Connected ... Please type message now");
            var message = "Hey";
            // 再调用SendMessage方法
            await connection.InvokeAsync("SendMessage", message);
            Console.WriteLine(connection.ConnectionId);
        }
        // 阻止程序立即退出,确保能接收消息
        Console.ReadLine();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

额外补充:控制台应用执行完Main方法会直接退出,添加Console.ReadLine()可以让程序保持运行状态,确保能接收到服务端推送的消息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:21:59