SignalR注入IHubContext后调用Whisper方法客户端断点未触发问题解决
SignalR注入IHubContext调用客户端方法无响应的解决办法
问题描述
客户端通过SignalR与网关服务建立连接,网关接收HTTP请求后生成命令并推送至RabbitMQ,由独立微服务处理该命令。当前遇到的问题:注入IHubContext后调用客户端的Whisper方法时,方法内的断点未触发,且无任何报错信息,但OnConnectedAsync方法能正常执行。
解决方案
- 在命令处理器(如
JoinChatHandler)中注入IHubContext<ChatHub>或强类型版本IHubContext<ChatHub, IChatClient> - 确保命令处理器以单例模式注册到依赖注入容器,使用以下代码:
builder.Services.AddSingleton<ICommandHandler<JoinChat>, JoinChatHandler>();
相关代码示例
IChatClient 强类型客户端接口
public interface IChatClient { Task<bool> Whisper(string message); }
ChatHub 实现类
[Service(ServiceLifetime.Singleton)] public class ChatHub : Hub<IChatClient> { private readonly IMessageService _messageService; private readonly IChatService _chatService; private readonly ILogger<ChatHub> _logger; public ChatHub(IMessageService messageService, IChatService chatService, ILogger<ChatHub> logger) { _messageService = messageService; _chatService = chatService; _logger = logger; } public override async Task OnConnectedAsync() { _logger.LogInformation("连接已建立"); await base.OnConnectedAsync(); } public override async Task OnDisconnectedAsync(Exception exception) { // 从聊天房间移除用户的逻辑 await base.OnDisconnectedAsync(exception); } public async Task<bool> Whisper(string message) { try { // await Clients.Caller.ReceiveMessage(message); return true; } catch (IOException ex) { _logger.LogError(ex, "向客户端写入消息时出错。"); Context.Abort(); return false; } } }
JoinChatHandler 命令处理器
[Service(ServiceLifetime.Singleton)] public class JoinChatHandler : ICommandHandler<JoinChat> { private readonly ILogger<JoinChatHandler> _logger; private readonly IBusPublisher _busPublisher; private readonly IHubContext<ChatHub, IChatClient> _hubContext; public JoinChatHandler(ILogger<JoinChatHandler> logger, IBusPublisher busPublisher, IHubContext<ChatHub, IChatClient> hubContext) { _logger = logger; _busPublisher = busPublisher; _hubContext = hubContext; } public async Task HandleAsync(JoinChat command, ICorrelationContext context) { var client = _hubContext.Clients.Client(command.ConnectionId); try { var t = await client.Whisper("AAA"); } catch (Exception e) { Console.WriteLine(e); } } }
Program.cs 核心配置片段
var builder = WebApplication.CreateBuilder(args); // ... 其他服务注册代码 ... builder.Services .AddMongo() .AddMongoRepository<ChatEntity>("chats") .AddMongoRepository<MessageEntity>("messages") .AddSingleton<ChatRepository>() .AddSingleton<MessageRepository>() // 关键:单例注册命令处理器 .AddSingleton<ICommandHandler<JoinChat>, JoinChatHandler>(); // ... 中间件配置 ... // 映射SignalR Hub app.MapHub<ChatHub>("/chatHub"); app.Run();
内容的提问来源于stack exchange,提问作者Kirill Topchy
相关产品推荐
相关产品推荐

