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

.Net ClientWebSocket ReceiveAsync报错:远程方未完成握手关闭连接

错误原因分析
  • 服务器端因消息合法性/格式问题主动断连:比如替换token后的connectMsg不符合服务器协议规范(如JSON格式错误、必填字段缺失),或者token无效,服务器收到消息后直接断开连接,未执行标准关闭握手流程。
  • 客户端未处理分片消息:如果服务器发送的是分片式消息,当前代码仅处理单帧数据,未拼接完整消息,可能导致后续接收逻辑异常触发断连。
  • 连接超时被服务器强制回收:服务器可能设置了连接超时阈值,客户端发送初始消息后未维持心跳,被服务器主动断开。
  • 客户端接收逻辑存在隐患:复用固定reciveBuffer可能导致数据覆盖,或HandleMessage处理耗时过长阻塞接收流程,引发连接异常。
解决步骤
  1. 验证消息与token有效性

    • 确认connectMsg替换token后的内容完全匹配服务器要求(比如是否为标准JSON、字段是否完整)。
    • 用WebSocket测试工具(如wscat)手动发送相同消息,验证服务器是否正常响应,排除客户端代码外的问题。
    • 检查token是否过期、权限是否符合服务器要求。
  2. 完善分片消息处理逻辑
    当前代码仅处理单帧消息,需修改为拼接完整消息后再处理:

    var reciveBuffer = new byte[32000];
    var messageBuffer = new List<byte>();
    
    while (socket.State == WebSocketState.Open)
    {
        var result = await socket.ReceiveAsync(new ArraySegment<byte>(reciveBuffer), CancellationToken.None);
    
        if (result.MessageType == WebSocketMessageType.Close)
        {
            await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
            break;
        }
        else
        {
            messageBuffer.AddRange(reciveBuffer.Take(result.Count));
            // 确认消息接收完成(EndOfMessage为true)再处理
            if (result.EndOfMessage)
            {
                await HandleMessage(messageBuffer.ToArray(), messageBuffer.Count);
                messageBuffer.Clear();
            }
        }
    }
    
  3. 添加心跳机制维持连接
    若服务器有超时设置,定期发送心跳包避免连接被强制断开:

    // 连接成功后启动心跳任务
    var heartbeatTokenSource = new CancellationTokenSource();
    var heartbeatTask = Task.Run(async () =>
    {
        while (!heartbeatTokenSource.Token.IsCancellationRequested && socket.State == WebSocketState.Open)
        {
            await Task.Delay(30000, heartbeatTokenSource.Token);
            if (socket.State == WebSocketState.Open)
            {
                var heartbeatBuffer = new ArraySegment<byte>(Encoding.ASCII.GetBytes("heartbeat"));
                await socket.SendAsync(heartbeatBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
            }
        }
    }, heartbeatTokenSource.Token);
    
    // 连接关闭时取消心跳任务
    // ...
    heartbeatTokenSource.Cancel();
    await heartbeatTask;
    
  4. 优化异常处理
    在ReceiveAsync外围添加异常捕获,获取更详细错误信息:

    while (socket.State == WebSocketState.Open)
    {
        try
        {
            var result = await socket.ReceiveAsync(new ArraySegment<byte>(reciveBuffer), CancellationToken.None);
            // 原消息处理逻辑
        }
        catch (WebSocketException ex)
        {
            Console.WriteLine($"WebSocket异常: {ex.Message}, 错误码: {ex.WebSocketErrorCode}");
            // 根据错误码判断是否重连或终止
            break;
        }
    }
    
  5. 排查服务器端日志
    联系服务器开发/运维人员,查看WebSocket连接日志,确认服务器主动断连的具体原因(如消息校验失败、资源限制等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:50:42