.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
相关产品推荐
相关产品推荐

