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

SignalR客户端未执行connection.on方法问题求助

解决SignalR服务端发消息客户端收不到的问题

从你的代码来看,有几个关键问题导致客户端无法接收消息,我逐个给你分析并提供修复方案:

1. BackgroundService未保持长期运行,连接被释放

你的Worker类继承自BackgroundService,但ExecuteAsync方法执行到注册回调后就直接结束了。BackgroundService的设计逻辑是:当ExecuteAsync方法完成时,服务会停止,这时候你的SignalR连接会被自动释放,后续服务端发消息时客户端已经处于断开状态,自然收不到消息。

修复方案:在ExecuteAsync中添加长期运行的循环逻辑,监听停止令牌,保持服务持续运行:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    using (StreamWriter writer = new StreamWriter(@"C:\Users\devma\source\repos\WorkerService1\WorkerService1\TextFile1.txt"))
    {
        writer.WriteLine("bigin");
    }
    var ip = GetLocalIPAddress();
    ip = "localhost";
    connection = new HubConnectionBuilder()
        .WithUrl("https://localhost:44339/dschub" , options => {
            options.WebSocketConfiguration = conf => {
                conf.RemoteCertificateValidationCallback = (message, cert, chain, errors) => true;
            };
            options.HttpMessageHandlerFactory = factory => new HttpClientHandler {
                ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
            };
        } )
        .Build();

    // 先注册所有回调,再启动连接(关键!避免漏接消息)
    connection.On<string>("calldscclient", (message) => {
        using (StreamWriter writer = new StreamWriter(@"C:\Users\devma\source\repos\WorkerService1\WorkerService1\TextFile1.txt"))
        {
            writer.WriteLine($"Received message: {message}");
            writer.WriteLine("Monica Rathbun");
        }
    });

    // 添加自动重连逻辑,应对网络波动
    connection.Closed += async (error) =>
    {
        _logger.LogWarning("SignalR connection closed, attempting reconnect...");
        await Task.Delay(new Random().Next(0, 5) * 1000);
        try
        {
            await connection.StartAsync(stoppingToken);
            await connection.InvokeAsync("dscRegister", ip, stoppingToken);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Reconnect failed");
        }
    };

    // 启动连接并注册客户端
    try
    {
        await connection.StartAsync(stoppingToken);
        await connection.InvokeAsync("dscRegister", ip, stoppingToken);
        _logger.LogInformation("SignalR connection established");
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Failed to start SignalR connection");
    }

    // 保持服务运行,直到收到停止信号
    await Task.Delay(Timeout.Infinite, stoppingToken);
}

2. 回调注册时机太晚

你之前是在StartAsync和InvokeAsync("dscRegister")之后才注册calldscclient回调,如果dscRegister的服务端方法触发了消息发送,或者服务端在客户端注册回调前就发了消息,客户端是收不到的。一定要在启动连接前注册所有回调,确保客户端能接收所有后续消息。

3. 服务端可能错误注入Hub实例

在ASP.NET Core SignalR中,不能直接注入Hub类的实例(比如你的_hub),因为Hub是为每个连接创建的临时对象,直接注入的实例无法正确对应到客户端连接。正确的做法是注入IHubContext<YourHub>来发送消息。

服务端修复示例:
假设你的Hub类叫DscHub,先通过构造函数注入IHubContext<DscHub>:

private readonly IHubContext<DscHub> _hubContext;
private readonly IDscService _dscService;

// 构造函数注入IHubContext
public YourController(IHubContext<DscHub> hubContext, IDscService dscService)
{
    _hubContext = hubContext;
    _dscService = dscService;
}

[HttpGet("servedsc")]
public async Task<ActionResult> ServeDsc()
{
    var remoteIpAddress = HttpContext.Request.Host.Host;
    var desUserList = await _dscService.GetDscUser(remoteIpAddress);
    var targetConnectionId = desUserList.FirstOrDefault()?.DscConnectionId;
    
    if (!string.IsNullOrEmpty(targetConnectionId))
    {
        // 给指定连接发消息(比发给所有人更精准,避免无效推送)
        await _hubContext.Clients.Client(targetConnectionId).SendAsync("calldscclient", targetConnectionId);
    }
    return Ok(desUserList);
}

4. 额外建议:添加日志排查问题

在客户端的连接事件中添加日志,方便快速定位连接状态问题:

// 连接重连成功日志
connection.Reconnected += (connectionId) =>
{
    _logger.LogInformation("SignalR reconnected with id: {ConnectionId}", connectionId);
    return Task.CompletedTask;
};

// 正在重连日志
connection.Reconnecting += (error) =>
{
    _logger.LogWarning("SignalR reconnecting due to error: {Error}", error?.Message);
    return Task.CompletedTask;
};

按照上面的步骤修改后,应该就能解决客户端收不到消息的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:50:47