.Net ClientWebSocket ReceiveAsync报错:远程方未完成握手关闭连接
错误原因分析
- 服务器端因消息合法性/格式问题主动断连:比如替换token后的
connectMsg不符合服务器协议规范(如JSON格式错误、必填字段缺失),或者token无效,服务器收到消息后直接断开连接,未执行标准关闭握手流程。 - 客户端未处理分片消息:如果服务器发送的是分片式消息,当前代码仅处理单帧数据,未拼接完整消息,可能导致后续接收逻辑异常触发断连。
- 连接超时被服务器强制回收:服务器可能设置了连接超时阈值,客户端发送初始消息后未维持心跳,被服务器主动断开。
- 客户端接收逻辑存在隐患:复用固定
reciveBuffer可能导致数据覆盖,或HandleMessage处理耗时过长阻塞接收流程,引发连接异常。
解决步骤
验证消息与token有效性
- 确认
connectMsg替换token后的内容完全匹配服务器要求(比如是否为标准JSON、字段是否完整)。 - 用WebSocket测试工具(如wscat)手动发送相同消息,验证服务器是否正常响应,排除客户端代码外的问题。
- 检查token是否过期、权限是否符合服务器要求。
- 确认
完善分片消息处理逻辑
当前代码仅处理单帧消息,需修改为拼接完整消息后再处理: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(); } } }添加心跳机制维持连接
若服务器有超时设置,定期发送心跳包避免连接被强制断开:// 连接成功后启动心跳任务 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;优化异常处理
在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; } }排查服务器端日志
联系服务器开发/运维人员,查看WebSocket连接日志,确认服务器主动断连的具体原因(如消息校验失败、资源限制等)。
内容的提问来源于stack exchange,提问作者MarchalPT
相关产品推荐
相关产品推荐

