模块契约WebSocket 协议底座

所有权与错误

帧、消息、Close、握手和扩展解析器只借用输入视图;成功后也不会接管输入。所有写出函数使用 调用方缓冲,并在容量不足时返回所需长度,不留下半个结构。Upgrade 结果拥有 Accept 与扩展响应, 子协议暂时借用 HTTP Header;Attach 会在消费 Header 前复制它。Inflater、Deflater 和 Stream 持有资源,必须由对应 Destroy 释放。

协议错误通过稳定的模块错误码和 xrtGetError/结构化错误链表达。输入不足不是协议错误; 只有确定违反协议、参数范围、资源上限、输出回调或压缩状态时才进入失败路径。

线程

帧、消息与扩展协商 API 为无共享状态的纯函数,可任意线程并发调用;流对象与压缩/解压上下文为单拥有者对象,绑定其所属 Worker 或创建线程。

模块边界

层次模块能力
帧websocket_frame帧头解析、帧头写出、分片 mask
关闭websocket_closeClose code、UTF-8 reason、payload 解析与写出
消息websocket_message分片、控制帧穿插、角色规则、UTF-8 和消息上限
握手websocket_handshake、websocket_keygenKey、Accept、版本、子协议和 Upgrade 字段
扩展websocket_extension、websocket_deflate扩展字段与 permessage-deflate 协商
压缩websocket_inflater、websocket_deflater有界、流式、可复用的消息压缩与解压
Upgradewebsocket_upgrade、websocket_upgrade_deflate完整 HTTP/1.1 Upgrade 校验、字段写出和压缩协商
通信websocket_stream、websocket_stream_tlsTCP/TLS 接管、消息事件、背压和关闭握手
组合websocket_upgrade_stream把基础协商结果直接映射为 Stream 配置,不强制带入压缩
压缩组合websocket_upgrade_stream + websocket_upgrade_deflate + websocket_stream_deflateUpgrade、Stream 与 permessage-deflate 完整链路

每层都可以独立裁剪。仅选择帧层不会带入 HTTP、网络、TLS 或压缩;Upgrade 层才依赖 HTTP/1; TCP Stream、TLS 适配和压缩发送分别独立启用。websocket_upgrade_stream 本身不依赖压缩,只有同时 选择 websocket_upgrade_deflate 与 websocket_stream_deflate 才启用协商后的压缩链路。任何核心组合 都不会带入 Future、协程或任务系统。

高性能收发

发送端使用 xrtWsFrameWrite 在调用方栈内存或固定小缓冲中生成最多 14 字节的帧头,随后将帧头和 payload 作为两个片段直接交给 xrtNetStreamSendRefs、TLS 写入器或调用方自己的向量发送接口。 模块不会聚合、复制或暂存完整报文。客户端 payload 必须使用 xrtWsMask 处理;该函数接受 offset, 因此可以跨任意数量的输入分片保持 mask 相位。

接收端先向 xrtWsFrameParse 提供当前可见字节。返回 XWS_FRAME_MORE 时继续累积最多 14 字节帧头; 返回 XWS_FRAME_READY 后,调用方按 PayloadSize 直接消费网络缓冲中的 payload。每个分片依次经过 xrtWsMessageFrameBegin、xrtWsMessagePayload 和 xrtWsMessageFrameEnd,正文仍借用原网络缓冲, 无需构造完整消息副本。

这种边界允许应用自行选择纯协议原语,或使用 xwsstream 完成标准事件驱动通信。更高层仍可在 同一底座上组合同步等待、Future 或协程,核心不会隐藏背压。

轻量 Stream

xrtWsStreamAttach 与 xrtWsStreamAttachTls 接管已经完成 Upgrade 的 TCP/TLS 调用方引用。 iPrefix 是已经验证但尚未消费的 HTTP Header 长度:接管时先复制协商出的子协议,再精确消费 Header,最后异步处理同一缓冲中的帧余量。失败不会部分接管传输。

接收事件按 MessageBegin、零个或多个 MessageData、MessageEnd 发布。正文视图只在当前同步 回调有效,Stream 不聚合完整消息,也不为每条连接预分配固定 8 KiB 缓冲;TCP/TLS 现有块链直接 进入帧和消息状态机。TLS 帧头跨 record 时,Stream 通过受 PlainLimit 限制的 ReadMore 路径 累积最多 14 字节的完整帧头,不会因保留一个不完整前缀而停住。

发送 API 提供 copy 和可选 ref 路径,压缩发送按需创建 Deflater。SendLimit 是 WebSocket 与 底层传输待发量的统一硬边界,达到上限返回 XNET_RESULT_AGAIN;Backpressure、Writable 和 Drain 给出恢复边沿。Ping 可自动回复,Close 保证唯一发送、超时和对端终态快照。

帧与消息契约

xwsframe 描述 FIN、RSV、opcode、mask 和 63 位 payload 长度。严格解析拒绝:

  • 非最短长度编码和超过 63 位的长度;
  • 保留或未允许的 opcode、RSV 位;
  • 分片控制帧或超过 125 字节的控制帧;
  • 不符合客户端/服务端角色的 mask;
  • 输出范围重叠、地址回绕和无效配置。

xrtWsFrameConfigInit 的 Mask 默认为 XWS_MASK_ANY,只用于角色未知的协议工具和 中间层。端点直接使用帧解析器时,服务端必须改为 XWS_MASK_REQUIRED,客户端必须改为 XWS_MASK_FORBIDDEN;xwsstream 已按连接角色自动设置该策略。

xwsmessagestate 不保存完整消息,只记录协议状态。它验证 continuation 顺序、Text UTF-8、 控制帧穿插、Close payload、扩展位和解码后消息上限。Ping/Pong/Close 由返回的消息标志交给调用方处理; 核心不自动回复、不自动关闭网络流。消息状态配置默认 MaxSize = SIZE_MAX,因为这一层不聚合正文; 任何收集完整消息或持有正文的上层都必须设置符合自身内存预算的有限上限。面向不可信对端时, xrtWsMessageConfigInitSafe 以 XWS_MESSAGE_SIZE_SAFE_DEFAULT(16 MiB)作为默认 消息上限初始化配置,防止恶意超长消息耗尽内存;需要无上限流时必须显式恢复 MaxSize = SIZE_MAX。XRT stream 层已提供自己的连接级默认限制。

握手与扩展

握手函数只处理 HTTP 字段值:

  • 验证或生成 Sec-WebSocket-Key;
  • 计算并验证 Sec-WebSocket-Accept;
  • 解析、检查、选择和写出子协议列表;
  • 检查方法、状态、版本、Upgrade、Connection、Host 和正文约束;
  • 遍历、计数和写出扩展及参数。

xrtWsUpgradeRequestCheck 和 xrtWsUpgradeResponseCheck 对完整 xhttp1head 执行角色相关校验, 包括唯一 Host、GET/101、HTTP/1.1、Key/Accept 绑定、版本 13、Connection、Upgrade、正文禁止、 子协议和扩展协商。重复字段按线路顺序处理,重复子协议和歧义响应会被拒绝。

xrtWsUpgradeRequestFields、xrtWsUpgradeResponseFields 只填充调用方字段描述符,可继续与 xrtHttp1RequestWrite、xrtHttp1ResponseWrite 组合。TCP 使用 xrtHttp1*ParseBuffer,TLS 使用 xrtHttp1*ParseTls;后者在 Header 跨 TLS record 时自动请求有界增量明文。成功后把 Head.Bytes 直接传给 Attach,Upgrade 后已经到达的帧不会丢失。

生产客户端必须通过 xrtWsKeyGenerate 使用安全随机数生成 Key;示例固定值只能用于协议测试。

permessage-deflate

协商层严格区分 offer 与 response,拒绝重复参数、非法 window bits、未知响应能力和不一致的 context takeover。xrtWsDeflateDirection 将协商结果转换为单方向运行参数。

xwsinflater 与 xwsdeflater 都是流式对象:

  • 输入和输出按分片推进,不聚合整条消息;
  • 输出通过回调直接进入调用方缓冲或网络发送队列;
  • 解压总量受消息上限和 Inflate 上限双重约束;
  • no-context-takeover 在消息边界重置字典;
  • xrtWsDeflaterBound 可在写入前完成容量规划;
  • 回调失败、OOM 或数据错误后具有明确的 reset、abort 或 destroy 路径。

RSV1 只允许出现在压缩消息的首个数据帧,continuation 不重复 RSV1,控制帧永不压缩。

扩展能力

连接对象、Writer、Future/协程桥接、重连与心跳策略、连接组和广播属于独立发布的 xws 扩展。基础 TCP/TLS 通信、关闭、背压和连接级压缩留在 XRT;xws 在这条稳定路径上提供高级抽象。

测试与示例

tests/websocket/ 覆盖固定向量、分块矩阵、属性测试、no-allocation、OOM、协议模糊测试,以及 真实 Select 回环上的 ws/wss Upgrade。集成测试会拆分 TLS Header 和一字节帧头,并验证压缩 发送、解压接收和完整 Close。examples/websocket/ 不依赖高级连接对象。

xwsstreamstate类型

WebSocket Stream 只包含开放、关闭握手和传输终态。

值语义
XWS_STREAM_OPENOPEN
XWS_STREAM_CLOSING关闭中
XWS_STREAM_CLOSED已关闭
typedef enum xwsstreamstate { XWS_STREAM_OPEN = 0, XWS_STREAM_CLOSING, XWS_STREAM_CLOSED } xwsstreamstate;

xwsstreamerror类型

Stream 错误区分协议、资源、发送和底层传输边界。

值语义
XWS_STREAM_ERROR_ARGUMENT参数非法
XWS_STREAM_ERROR_CONFIG配置非法
XWS_STREAM_ERROR_MEMORY内存分配失败
XWS_STREAM_ERROR_STATE状态非法
XWS_STREAM_ERROR_FRAME失败
XWS_STREAM_ERROR_MESSAGE消息
XWS_STREAM_ERROR_RANDOM失败
XWS_STREAM_ERROR_SEND发送方向
XWS_STREAM_ERROR_LIMIT超限
XWS_STREAM_ERROR_TRANSPORT失败
XWS_STREAM_ERROR_TIMEOUT超时
typedef enum xwsstreamerror { XWS_STREAM_ERROR_ARGUMENT = 1, XWS_STREAM_ERROR_CONFIG, XWS_STREAM_ERROR_MEMORY, XWS_STREAM_ERROR_STATE, XWS_STREAM_ERROR_FRAME, XWS_STREAM_ERROR_MESSAGE, XWS_STREAM_ERROR_RANDOM, XWS_STREAM_ERROR_SEND, XWS_STREAM_ERROR_LIMIT, XWS_STREAM_ERROR_TRANSPORT, XWS_STREAM_ERROR_TIMEOUT } xwsstreamerror;

xwsstreamcloseflag类型

Close 标志描述本地、远端和 RFC 6455 完整关闭结果。

值语义
XWS_STREAM_CLOSE_SENTSENT
XWS_STREAM_CLOSE_RECEIVEDRECEIVED
XWS_STREAM_CLOSE_CLEANCLEAN
XWS_STREAM_CLOSE_REMOTE对端发起关闭
typedef enum xwsstreamcloseflag { XWS_STREAM_CLOSE_SENT = UINT32_C(0x00000001), XWS_STREAM_CLOSE_RECEIVED = UINT32_C(0x00000002), XWS_STREAM_CLOSE_CLEAN = UINT32_C(0x00000004), XWS_STREAM_CLOSE_REMOTE = UINT32_C(0x00000008)

xwsstreamconfig类型

消息和帧上限分别约束解码后语义与线路输入。 发送上限包含 WebSocket 与底层传输待发字节;控制预算保留 Ping、Pong 和 Close。 Stream 不分配固定接收缓冲,协议数据直接消费 TCP 或 TLS 的现有缓冲链。

字段类型语义
Rolexwsrole角色
ProtocolxstrviewProtocol
MessageLimitsize_tMessageLimit
FrameLimituint64FrameLimit
SendLimitsize_tSendLimit
ControlReservesize_tControlReserve
CloseTimeoutuint64CloseTimeout
AutoPongboolAutoPong
DeflatexwsdeflateDeflate
InflaterxwsinflaterconfigInflater
DeflaterxwsdeflaterconfigDeflater
DeflateEnabledboolDeflateEnabled
typedef struct xwsstreamconfig { xwsrole Role; xstrview Protocol; size_t MessageLimit; uint64 FrameLimit; size_t SendLimit; size_t ControlReserve; int64 CloseTimeout; bool AutoPong; xwsdeflate Deflate; xwsinflaterconfig Inflater; xwsdeflaterconfig Deflater; bool DeflateEnabled; } xwsstreamconfig;

xwsstreamclose类型

Reason 借用 Stream 内部不可变副本,至少保持到 Stream 销毁。

字段类型语义
Flagsuint32标志位
TransportxnetresultTransport
LocalCodeuint16LocalCode
RemoteCodeuint16RemoteCode
Reasonxstrview原因文本
typedef struct xwsstreamclose { uint32 Flags; xnetresult Transport; uint16 LocalCode; uint16 RemoteCode; xstrview Reason; } xwsstreamclose;

xwsstreamevents类型

数据消息按 Begin、零个或多个 Data、End 流式发布,不拼接完整消息。 回调视图只在当前同步调用期间有效,全部事件在传输所属 Worker 上串行执行。

字段类型语义
MessageBeginvoid (*MessageBegin)( xwsstream* pStream, const xwsmessageinfo* pInfo, ptr pData )消息开始(含元信息)
MessageDatavoid (*MessageData)( xwsstream* pStream, xbytesview Data, ptr pData )消息分片
MessageEndvoid (*MessageEnd)(xwsstream* pStream, ptr pData)消息结束
Pongvoid (*Pong)( xwsstream* pStream, xbytesview Payload, ptr pData )收到 Pong
Backpressurevoid (*Backpressure)( xwsstream* pStream, size_t iPending, ptr pData )发送占用越过高水位
Writablevoid (*Writable)( xwsstream* pStream, size_t iPending, ptr pData )发送占用落回
Drainvoid (*Drain)(xwsstream* pStream, ptr pData)发送队列排空
Closevoid (*Close)( xwsstream* pStream, const xwsstreamclose* pClose, ptr pData )流关闭(含 Close 帧信息)
typedef struct xwsstreamevents { void(*MessageBegin)( xwsstream* pStream, const xwsmessageinfo* pInfo, ptr pData ); void (*MessageData)( xwsstream* pStream, xbytesview Data, ptr pData ); void (*MessageEnd)(xwsstream* pStream, ptr pData); void (*Ping)( xwsstream* pStream, xbytesview Payload, ptr pData ); void (*Pong)( xwsstream* pStream, xbytesview Payload, ptr pData ); void (*Backpressure)( xwsstream* pStream, size_t iPending, ptr pData ); void (*Writable)( xwsstream* pStream, size_t iPending, ptr pData ); void (*Drain)(xwsstream* pStream, ptr pData); void (*Error)( xwsstream* pStream, const xerror* pError, ptr pData ); void (*Close)( xwsstream* pStream, const xwsstreamclose* pClose, ptr pData)

xwsstream类型

WebSocket 流对象(不透明):组合传输上的帧/消息层,绑定所属 Worker。 不透明句柄或别名;生命周期与所有权见各使用方 API 节。

typedef struct xwsstream xwsstream;
扩展能力

xrtWsStreamConfigInit函数

初始化流层默认配置。

void xrtWsStreamConfigInit(xwsstreamconfig* pConfig)

参数

参数方向约束说明
pConfig输出非空接收配置
返回值
返回含义失败时状态
无已初始化—
错误
  • 无 — 初始化不失败

范例已编译验证

stream_tour · 流配置

	xrtWsStreamConfigInit(&pEnd->Config);

xrtWsStreamConfigValid函数

校验流层配置自洽。

bool xrtWsStreamConfigValid(const xwsstreamconfig* pConfig)

参数

参数方向约束说明
pConfig输入非空待校验配置
返回值
返回含义失败时状态
true是自洽—
false不是自洽—
错误
  • 无 — 纯校验,不设置错误

范例已编译验证

stream_tour · 流配置校验

	if ( !xrtWsStreamConfigValid(&Client.Config) ) goto Cleanup;

xrtWsStreamAttach函数

在已就绪的 TCP 流上挂接 WebSocket 流层。

xwsstream* xrtWsStreamAttach(xnetstream* pTransport, size_t iPrefix, const xwsstreamconfig* pConfig, const xwsstreamevents* pEvents, ptr pData)

参数

参数方向约束说明
pTransport输入非空传输 TCP 流
iPrefix输入—前缀已消费字节
pConfig输入允许空流配置
pEvents输入允许空事件表
pData输入任意值用户数据
返回值
返回含义失败时状态
非空WebSocket 流(引用 1)—
NULL挂接失败XERR_ARGUMENT 等
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_STATE — 传输流非开放状态
  • XERR_MEMORY — 分配失败

范例已编译验证

stream_tour · 挂接 TCP

	pEnd->pStream = xrtWsStreamAttach(pEnd->pTcp, 0,
		&pEnd->Config, &Events, pEnd);

xrtWsStreamAttachTls函数

在已就绪的 TLS 流上挂接 WebSocket 流层。

xwsstream* xrtWsStreamAttachTls(xtlsstream* pTransport, size_t iPrefix, const xwsstreamconfig* pConfig, const xwsstreamevents* pEvents, ptr pData)

参数

参数方向约束说明
pTransport输入非空传输 TLS 流
iPrefix输入—前缀已消费字节
pConfig输入允许空流配置
pEvents输入允许空事件表
pData输入任意值用户数据
返回值
返回含义失败时状态
非空WebSocket 流(引用 1)—
NULL挂接失败XERR_ARGUMENT 等
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_STATE — 传输流非开放状态
  • XERR_MEMORY — 分配失败

范例已编译验证

stream_tour · 挂接 TLS

			(xrtWsStreamAttachTls(NULL, 0, NULL, NULL, NULL) == NULL);

xrtWsStreamRef函数

增加流引用并返回原指针。

xwsstream* xrtWsStreamRef(xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
非空原指针,引用 +1—
NULL参数非法XERR_ARGUMENT
错误
  • XERR_ARGUMENT — 指针为空或参数非法

范例已编译验证

stream_tour · 共享引用

	pClientRef = xrtWsStreamRef(Client.pStream);

xrtWsStreamDestroy函数

释放流引用;关闭必须另行请求。

void xrtWsStreamDestroy(xwsstream* pStream)

参数

参数方向约束说明
pStream输入允许空空 = 空操作
返回值
返回含义失败时状态
无引用 -1—
错误
  • 无 — 释放不失败

范例已编译验证

stream_tour · 释放引用

		xrtWsStreamDestroy(pEnd->pStream);

xrtWsStreamSend函数

按操作码发送原始帧载荷。

xnetresult xrtWsStreamSend(xwsstream* pStream, xwsopcode Opcode, xbytesview Payload)

参数

参数方向约束说明
pStream输入非空目标流
Opcode输入—操作码
Payload输入借用载荷
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭

范例已编译验证

stream_tour · 发送帧

		(xrtWsStreamSend(pStream, pEnd->Opcode,
			(xbytesview) { (cbytes)pEnd->Buffer, pEnd->Size }) !=
			XNET_RESULT_OK) ) {

xrtWsStreamSendCompressed函数

按操作码压缩发送帧载荷。

xnetresult xrtWsStreamSendCompressed(xwsstream* pStream, xwsopcode Opcode, xbytesview Payload)

参数

参数方向约束说明
pStream输入非空目标流
Opcode输入—操作码
Payload输入借用载荷
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭

范例已编译验证

stream_tour · 压缩发送帧

		(xrtWsStreamSendCompressed(pJob->pStream, XWS_OPCODE_TEXT,
			(xbytesview) { (cbytes)"c-s", 3 }) == XNET_RESULT_OK);

xrtWsStreamSendRef函数

零复制发送帧载荷,离开队列时执行释放过程。

xnetresult xrtWsStreamSendRef(xwsstream* pStream, xwsopcode Opcode, const xnetref* pRef)

参数

参数方向约束说明
pStream输入非空目标流
Opcode输入—操作码
pRef输入非空引用
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭

范例已编译验证

stream_tour · 零复制发送帧

	if ( xrtWsStreamSendRef(pStream, XWS_OPCODE_BINARY, &Ref) !=
		XNET_RESULT_OK ) goto Done;

xrtWsStreamSendTake函数

接管 XRT 分配的载荷并发送。

xnetresult xrtWsStreamSendTake(xwsstream* pStream, xwsopcode Opcode, ptr pData, size_t iSize)

参数

参数方向约束说明
pStream输入非空目标流
Opcode输入—操作码
pData输入允许空拥有的数据
iSize输入—字节数
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭
  • 受理失败时所有权不转移

范例已编译验证

stream_tour · 接管发送帧

	if ( xrtWsStreamSendTake(pStream, XWS_OPCODE_TEXT, pTake, 8) !=
		XNET_RESULT_OK ) goto Done;

xrtWsStreamText函数

发送 UTF-8 文本消息。

xnetresult xrtWsStreamText(xwsstream* pStream, xstrview Text)

参数

参数方向约束说明
pStream输入非空目标流
Text输入借用、严格 UTF-8文本
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭
  • XERR_PROTOCOL — 文本不是合法 UTF-8

范例已编译验证

stream_tour · 发送文本

	if ( (xrtWsStreamText(pStream, XRT_STR_LITERAL("hello ws")) !=
			XNET_RESULT_OK) ||
		(xrtWsStreamBinary(pStream,
			(xbytesview) { (cbytes)"\x01\x02\x03", 3 }) != XNET_RESULT_OK) ||
		(xrtWsStreamSend(pStream, XWS_OPCODE_TEXT,
			(xbytesview) { (cbytes)"plain-send", 10 }) != XNET_RESULT_OK) ) {

xrtWsStreamTextCompressed函数

压缩发送 UTF-8 文本消息。

xnetresult xrtWsStreamTextCompressed(xwsstream* pStream, xstrview Text)

参数

参数方向约束说明
pStream输入非空目标流
Text输入借用、严格 UTF-8文本
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭
  • XERR_PROTOCOL — 文本不是合法 UTF-8

范例已编译验证

stream_tour · 压缩发送文本

	pJob->Ok = (xrtWsStreamTextCompressed(pJob->pStream,
		XRT_STR_LITERAL("compressed")) == XNET_RESULT_OK) &&

xrtWsStreamTextRef函数

零复制发送文本消息。

xnetresult xrtWsStreamTextRef(xwsstream* pStream, const xnetref* pRef)

参数

参数方向约束说明
pStream输入非空目标流
pRef输入非空引用
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭

范例已编译验证

stream_tour · 零复制发送文本

	if ( xrtWsStreamTextRef(pStream, &Ref) != XNET_RESULT_OK ) goto Done;

xrtWsStreamTextTake函数

接管 XRT 分配的文本并发送。

xnetresult xrtWsStreamTextTake(xwsstream* pStream, str sText, size_t iSize)

参数

参数方向约束说明
pStream输入非空目标流
sText输入允许空拥有的文本
iSize输入—字节数
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭
  • 受理失败时所有权不转移

范例已编译验证

stream_tour · 接管发送文本

	if ( xrtWsStreamTextTake(pStream, pTake, 9) != XNET_RESULT_OK ) goto Done;

xrtWsStreamBinary函数

发送二进制消息。

xnetresult xrtWsStreamBinary(xwsstream* pStream, xbytesview Data)

参数

参数方向约束说明
pStream输入非空目标流
Data输入借用数据
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭

范例已编译验证

stream_tour · 发送二进制

		(xrtWsStreamBinary(pStream,
			(xbytesview) { (cbytes)"\x01\x02\x03", 3 }) != XNET_RESULT_OK) ||

xrtWsStreamBinaryCompressed函数

压缩发送二进制消息。

xnetresult xrtWsStreamBinaryCompressed(xwsstream* pStream, xbytesview Data)

参数

参数方向约束说明
pStream输入非空目标流
Data输入借用数据
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭

范例已编译验证

stream_tour · 压缩发送二进制

		(xrtWsStreamBinaryCompressed(pJob->pStream,
			(xbytesview) { (cbytes)"c-b", 3 }) == XNET_RESULT_OK) &&

xrtWsStreamBinaryRef函数

零复制发送二进制消息。

xnetresult xrtWsStreamBinaryRef(xwsstream* pStream, const xnetref* pRef)

参数

参数方向约束说明
pStream输入非空目标流
pRef输入非空引用
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭

范例已编译验证

stream_ref · 零复制发送二进制

	Result = xrtWsStreamBinaryRef(pConnection, &Ref);

xrtWsStreamBinaryTake函数

接管 XRT 分配的数据并发送。

xnetresult xrtWsStreamBinaryTake(xwsstream* pStream, bytes pData, size_t iSize)

参数

参数方向约束说明
pStream输入非空目标流
pData输入允许空拥有的数据
iSize输入—字节数
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭
  • 受理失败时所有权不转移

范例已编译验证

stream_tour · 接管发送二进制

	if ( xrtWsStreamBinaryTake(pStream, pTake, 10) != XNET_RESULT_OK ) goto Done;

xrtWsStreamPing函数

发送 Ping 控制帧。

xnetresult xrtWsStreamPing(xwsstream* pStream, xbytesview Payload)

参数

参数方向约束说明
pStream输入非空目标流
Payload输入借用、<= 125 字节载荷
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭
  • XERR_RANGE — 控制帧载荷超过 125 字节

范例已编译验证

stream_tour · 发送 Ping

	pJob->Ok = (xrtWsStreamPing(pStream,
		(xbytesview) { (cbytes)"ping", 4 }) == XNET_RESULT_OK) &&

xrtWsStreamPong函数

发送 Pong 控制帧。

xnetresult xrtWsStreamPong(xwsstream* pStream, xbytesview Payload)

参数

参数方向约束说明
pStream输入非空目标流
Payload输入借用、<= 125 字节载荷
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭
  • XERR_RANGE — 控制帧载荷超过 125 字节

范例已编译验证

stream_tour · 发送 Pong

		(xrtWsStreamPong(pStream,
			(xbytesview) { (cbytes)"manual", 6 }) == XNET_RESULT_OK);

xrtWsStreamClose函数

发送 Close 帧并进入关闭握手。

xnetresult xrtWsStreamClose(xwsstream* pStream, uint16 iCode, xstrview Reason)

参数

参数方向约束说明
pStream输入非空目标流
iCode输入—关闭码
Reason输入借用原因文本
返回值
返回含义失败时状态
XNET_RESULT_OK操作成功—
XNET_RESULT_ERROR失败—
XNET_RESULT_AGAIN非阻塞暂不可推进—
XNET_RESULT_CLOSED对象已关闭—
XNET_RESULT_TRUNCATED结果被截断—
XNET_RESULT_TIMEOUT期限先到期—
XNET_RESULT_CANCELLED被取消—
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_AGAIN — 发送预算已满
  • XERR_STATE — 握手未完成或已关闭
  • XERR_PROTOCOL — 关闭码非法

范例已编译验证

stream_tour · 发送关闭

	pJob->Ok = xrtWsStreamClose(pJob->pStream, 1000,
		XRT_STR_LITERAL("done")) == XNET_RESULT_OK;

xrtWsStreamPause函数

暂停接收新数据。

void xrtWsStreamPause(xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
无已暂停—
错误
  • XERR_ARGUMENT — 指针为空或参数非法

范例已编译验证

stream_tour · 暂停接收

	xrtWsStreamPause(Client.pStream);

xrtWsStreamResume函数

恢复接收并唤醒所属 Worker。

bool xrtWsStreamResume(xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
true已恢复—
false状态非法XERR_STATE
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_STATE — 未处于暂停状态

范例已编译验证

stream_tour · 恢复接收

	if ( !xrtWsStreamResume(Client.pStream) ||
		!exampleWait(&Client.Received, iExpected + 11u) ||
		(memcmp(Client.Buffer + iExpected, "after-pause", 11u) != 0) ) goto Cleanup;

xrtWsStreamState函数

返回流当前生命周期状态。

xwsstreamstate xrtWsStreamState(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
状态枚举值当前状态—
错误
  • XERR_ARGUMENT — 指针为空或参数非法

范例已编译验证

stream_tour · 状态

		(xrtWsStreamState(Client.pStream) != XWS_STREAM_CLOSED) ||

xrtWsStreamRole函数

返回本端协商角色。

xwsrole xrtWsStreamRole(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
XWS_ROLE_CLIENT / XWS_ROLE_SERVER本端角色—
错误
  • XERR_ARGUMENT — 指针为空或参数非法

范例已编译验证

stream_tour · 角色

	if ( xrtWsStreamRole(pStream) == XWS_ROLE_SERVER ) pEnd->Size = 0;

xrtWsStreamProtocol函数

返回协商选中的子协议。

xstrview xrtWsStreamProtocol(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
视图子协议借用—
空视图未协商不设错误
错误
  • XERR_ARGUMENT — 指针为空或参数非法

范例已编译验证

stream_tour · 子协议

		(xrtWsStreamProtocol(Client.pStream).Size != 0) ||

xrtWsStreamDeflate函数

复制本流协商的压缩参数。

bool xrtWsStreamDeflate(const xwsstream* pStream, xwsdeflate* pDeflate)

参数

参数方向约束说明
pStream输入非空目标流
pDeflate输出非空接收参数
返回值
返回含义失败时状态
true已写出—
false未启用压缩不设错误
错误
  • 未启用 permessage-deflate 返回 false 且不设置错误

范例已编译验证

stream_tour · 压缩协商

		if ( !xrtWsStreamDeflate(Client.pStream, &Deflate) ||
			!exampleRun(pEngine, &Job, Client.pStream, exampleCompressedTask) ||
			!exampleWait(&Client.Received, iExpected + 16u) ||
			(memcmp(Client.Buffer + iExpected, "compressedc-bc-s", 16u) != 0) ) goto Cleanup;

xrtWsStreamCloseInfo函数

复制对端 Close 帧信息。

bool xrtWsStreamCloseInfo(const xwsstream* pStream, xwsstreamclose* pClose)

参数

参数方向约束说明
pStream输入非空目标流
pClose输出非空接收关闭描述
返回值
返回含义失败时状态
true已复制—
false未收到 Close不设错误
错误
  • 未收到 Close 帧返回 false 且不设置错误

范例已编译验证

stream_tour · 关闭信息

		!xrtWsStreamCloseInfo(Client.pStream, &CloseInfo) ||

xrtWsStreamError函数

返回导致流终止的借用错误。

const xerror* xrtWsStreamError(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
非空终止原因借用—
NULL正常关闭或未终止不设错误
错误
  • 无错误 — 正常关闭或未终止返回 NULL 且不设置错误

范例已编译验证

stream_tour · 终止错误

		(xrtWsStreamError(Client.pStream) != NULL) ||

xrtWsStreamAbort函数

立即丢弃发送队列并异常关闭。

bool xrtWsStreamAbort(xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
true已关闭—
false状态非法XERR_STATE
错误
  • XERR_ARGUMENT — 指针为空或参数非法
  • XERR_STATE — 已关闭

范例已编译验证

stream_tour · 异常关闭

		(void)xrtWsStreamAbort(pStream);

xrtWsStreamPending函数

返回发送队列占用字节数。

size_t xrtWsStreamPending(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
>= 0占用字节数—
错误
  • XERR_ARGUMENT — 指针为空或参数非法

范例已编译验证

stream_tour · 发送占用

	while ( (xrtWsStreamPending(Client.pStream) != 0u) ||
		(xrtWsStreamPending(Server.pStream) != 0u) ) {

xrtWsStreamWritable函数

返回剩余发送预算。

size_t xrtWsStreamWritable(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
>= 0剩余预算—
错误
  • XERR_ARGUMENT — 指针为空或参数非法

范例已编译验证

stream_tour · 剩余预算

	if ( (xrtWsStreamWritable(Client.pStream) == 0u) ||
		(xrtAtomic32Load(&Client.Received, XMEMORY_ACQUIRE) != iExpected) ||
		!exampleRun(pEngine, &Job, Client.pStream, exampleCloseTask) ||
		!exampleWait(&Client.Closed, 1) || !exampleWait(&Server.Closed, 1) ||
		!xrtWsStreamCloseInfo(Client.pStream, &CloseInfo) ||
		((CloseInfo.Flags & (XWS_STREAM_CLOSE_SENT | XWS_STREAM_CLOSE_RECEIVED |
			XWS_STREAM_CLOSE_CLEAN)) != (XWS_STREAM_CLOSE_SENT |
			XWS_STREAM_CLOSE_RECEIVED | XWS_STREAM_CLOSE_CLEAN)) ||
		(CloseInfo.RemoteCode != 1000u) ||
		(xrtWsStreamError(Client.pStream) != NULL) ||
		(xrtWsStreamError(Server.pStream) != NULL) ||

xrtWsStreamPaused函数

判断是否处于暂停状态。

bool xrtWsStreamPaused(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
true是暂停—
false不是暂停—
错误
  • XERR_ARGUMENT — 指针为空或参数非法

范例已编译验证

stream_tour · 暂停查询

	if ( !xrtWsStreamPaused(Client.pStream) ||
		!exampleRun(pEngine, &Job, Server.pStream, exampleAfterTask) ) goto Cleanup;

xrtWsStreamWorker函数

返回流所属的借用 Worker。

xnetworker* xrtWsStreamWorker(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
非空Worker 借用—
NULL参数非法XERR_ARGUMENT
错误
  • XERR_ARGUMENT — 指针为空或参数非法

范例已编译验证

stream_tour · 所属 Worker

		xrtNetWorkerIndex(xrtWsStreamWorker(pStream)), Proc, pJob) &&

xrtWsStreamTcp函数

返回底层 TCP 流借用(不增引用)。

xnetstream* xrtWsStreamTcp(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
非空TCP 流借用—
NULL非 TCP 传输不设错误
错误
  • 非 TCP 挂接返回 NULL 且不设置错误

范例已编译验证

stream_tour · TCP 借用

	pJob->Ok = (pTcp != NULL) && (xrtWsStreamTcp(pJob->pStream) == pTcp);

xrtWsStreamTcpRef函数

返回底层 TCP 流并增加引用。

xnetstream* xrtWsStreamTcpRef(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
非空TCP 流新引用—
NULL非 TCP 传输不设错误
错误
  • 非 TCP 挂接返回 NULL 且不设置错误

范例已编译验证

stream_tour · TCP 引用

	xnetstream* pTcp = xrtWsStreamTcpRef(pJob->pStream);

xrtWsStreamTls函数

返回底层 TLS 流借用(不增引用)。

xtlsstream* xrtWsStreamTls(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
非空TLS 流借用—
NULL非 TLS 传输不设错误
错误
  • 非 TLS 挂接返回 NULL 且不设置错误

范例已编译验证

stream_tour · TLS 借用

			(xrtWsStreamTls(pJob->pStream) == NULL) &&

xrtWsStreamTlsRef函数

返回底层 TLS 流并增加引用。

xtlsstream* xrtWsStreamTlsRef(const xwsstream* pStream)

参数

参数方向约束说明
pStream输入非空目标流
返回值
返回含义失败时状态
非空TLS 流新引用—
NULL非 TLS 传输不设错误
错误
  • 非 TLS 挂接返回 NULL 且不设置错误

范例已编译验证

stream_tour · TLS 引用

		xtlsstream* pTls = xrtWsStreamTlsRef(pJob->pStream);

常量索引常量

以下常量在本页所属头文件中定义,语义见公共头注释。

常量说明
XWS_STREAM_CLOSED见头文件注释
XWS_STREAM_CLOSE_CLEAN见头文件注释
XWS_STREAM_CLOSE_RECEIVED见头文件注释
XWS_STREAM_CLOSE_REMOTE见头文件注释
XWS_STREAM_CLOSE_SENT见头文件注释
XWS_STREAM_CLOSE_TIMEOUT_DEFAULT见头文件注释
XWS_STREAM_CLOSING见头文件注释
XWS_STREAM_CONTROL_RESERVE_DEFAULT见头文件注释
XWS_STREAM_ERROR_ARGUMENT见头文件注释
XWS_STREAM_ERROR_CONFIG见头文件注释
XWS_STREAM_ERROR_FRAME见头文件注释
XWS_STREAM_ERROR_LIMIT见头文件注释
XWS_STREAM_ERROR_MEMORY见头文件注释
XWS_STREAM_ERROR_MESSAGE见头文件注释
XWS_STREAM_ERROR_RANDOM见头文件注释
XWS_STREAM_ERROR_SEND见头文件注释
XWS_STREAM_ERROR_STATE见头文件注释
XWS_STREAM_ERROR_TIMEOUT见头文件注释
XWS_STREAM_ERROR_TRANSPORT见头文件注释
XWS_STREAM_FRAME_LIMIT_DEFAULT见头文件注释
XWS_STREAM_MESSAGE_LIMIT_DEFAULT见头文件注释
XWS_STREAM_OPEN见头文件注释
XWS_STREAM_SEND_LIMIT_DEFAULT见头文件注释