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

C# WebSocket 服务端如何向客户端主动回传消息?

问题原因

WebSocket 是基于TCP的上层应用层协议,所有服务端和客户端之间的交互数据都必须按照标准的WebSocket帧格式封装后才能传输。你直接将字符串转为ASCII字节写入流的操作没有遵循帧协议规范,客户端收到非法格式的数据后无法正常解析,会直接判定连接异常主动断开,因此会触发未定义错误。另外使用ASCII编码仅能支持英文字符,若后续传输包含特殊字符或中文内容会出现乱码,建议统一使用UTF8编码。

可行解决方案
  • 优先使用.NET官方封装的WebSocket类库
    .NET 框架System.Net.WebSockets命名空间已经内置了完整的WebSocket协议实现,无需手动处理帧结构的封装和解析,直接调用内置的发送方法即可,示例代码如下:
// 已完成握手后拿到WebSocket实例对象webSocket
byte[] responseBuffer = Encoding.UTF8.GetBytes("Message received by server");
await webSocket.SendAsync(
    new ArraySegment<byte>(responseBuffer, 0, responseBuffer.Length),
    WebSocketMessageType.Text,
    endOfMessage: true,
    cancellationToken: CancellationToken.None
);
  • 若场景要求手动实现帧封装逻辑
    如果你的项目需要自行实现底层帧处理,需要按照WebSocket协议标准拼接帧结构,长度小于126的文本帧基础拼接逻辑示例如下:
string responseMsg = "Message received by server";
byte[] payload = Encoding.UTF8.GetBytes(responseMsg);
// 帧总长度 = 2字节头部 + 负载长度
byte[] frameBuffer = new byte[2 + payload.Length];
// 第一个字节:FIN位为1(代表这是完整消息的最后一帧) + 操作码0x1(代表文本帧),组合为0x81
frameBuffer[0] = 0x81;
// 第二个字节:服务端发往客户端的帧不需要掩码,最高位为0,剩余7位填负载长度,小于126时直接写入
frameBuffer[1] = (byte)payload.Length;
// 将负载内容复制到帧缓冲区
Buffer.BlockCopy(payload, 0, frameBuffer, 2, payload.Length);
// 写入流发送
stream.Write(frameBuffer, 0, frameBuffer.Length);

注意如果发送的内容字节长度大于125,需要额外处理2字节的扩展长度字段;长度大于65535时需要使用8字节的扩展长度位,自行实现需要覆盖所有长度场景的兼容处理,否则仍会出现解析错误,非必要场景不推荐手动实现。

内容的提问来源于stack exchange,提问作者Mihnea Cristian Marin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 01:27:01