模块契约WebSocket 协议底座
所有权与错误
帧、消息、Close、握手和扩展解析器只借用输入视图;成功后也不会接管输入。所有写出函数使用 调用方缓冲,并在容量不足时返回所需长度,不留下半个结构。Upgrade 结果拥有 Accept 与扩展响应, 子协议暂时借用 HTTP Header;Attach 会在消费 Header 前复制它。Inflater、Deflater 和 Stream 持有资源,必须由对应 Destroy 释放。
协议错误通过稳定的模块错误码和 xrtGetError/结构化错误链表达。输入不足不是协议错误; 只有确定违反协议、参数范围、资源上限、输出回调或压缩状态时才进入失败路径。
线程
帧、消息与扩展协商 API 为无共享状态的纯函数,可任意线程并发调用;流对象与压缩/解压上下文为单拥有者对象,绑定其所属 Worker 或创建线程。
模块边界
| 层次 | 模块 | 能力 |
|---|---|---|
| 帧 | websocket_frame | 帧头解析、帧头写出、分片 mask |
| 关闭 | websocket_close | Close code、UTF-8 reason、payload 解析与写出 |
| 消息 | websocket_message | 分片、控制帧穿插、角色规则、UTF-8 和消息上限 |
| 握手 | websocket_handshake、websocket_keygen | Key、Accept、版本、子协议和 Upgrade 字段 |
| 扩展 | websocket_extension、websocket_deflate | 扩展字段与 permessage-deflate 协商 |
| 压缩 | websocket_inflater、websocket_deflater | 有界、流式、可复用的消息压缩与解压 |
| Upgrade | websocket_upgrade、websocket_upgrade_deflate | 完整 HTTP/1.1 Upgrade 校验、字段写出和压缩协商 |
| 通信 | websocket_stream、websocket_stream_tls | TCP/TLS 接管、消息事件、背压和关闭握手 |
| 组合 | websocket_upgrade_stream | 把基础协商结果直接映射为 Stream 配置,不强制带入压缩 |
| 压缩组合 | websocket_upgrade_stream + websocket_upgrade_deflate + websocket_stream_deflate | Upgrade、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_OPEN | OPEN |
XWS_STREAM_CLOSING | 关闭中 |
XWS_STREAM_CLOSED | 已关闭 |
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 | 超时 |
xwsstreamcloseflag类型
Close 标志描述本地、远端和 RFC 6455 完整关闭结果。
| 值 | 语义 |
|---|---|
XWS_STREAM_CLOSE_SENT | SENT |
XWS_STREAM_CLOSE_RECEIVED | RECEIVED |
XWS_STREAM_CLOSE_CLEAN | CLEAN |
XWS_STREAM_CLOSE_REMOTE | 对端发起关闭 |
xwsstreamconfig类型
消息和帧上限分别约束解码后语义与线路输入。 发送上限包含 WebSocket 与底层传输待发字节;控制预算保留 Ping、Pong 和 Close。 Stream 不分配固定接收缓冲,协议数据直接消费 TCP 或 TLS 的现有缓冲链。
| 字段 | 类型 | 语义 |
|---|---|---|
Role | xwsrole | 角色 |
Protocol | xstrview | Protocol |
MessageLimit | size_t | MessageLimit |
FrameLimit | uint64 | FrameLimit |
SendLimit | size_t | SendLimit |
ControlReserve | size_t | ControlReserve |
CloseTimeout | uint64 | CloseTimeout |
AutoPong | bool | AutoPong |
Deflate | xwsdeflate | Deflate |
Inflater | xwsinflaterconfig | Inflater |
Deflater | xwsdeflaterconfig | Deflater |
DeflateEnabled | bool | DeflateEnabled |
xwsstreamclose类型
Reason 借用 Stream 内部不可变副本,至少保持到 Stream 销毁。
| 字段 | 类型 | 语义 |
|---|---|---|
Flags | uint32 | 标志位 |
Transport | xnetresult | Transport |
LocalCode | uint16 | LocalCode |
RemoteCode | uint16 | RemoteCode |
Reason | xstrview | 原因文本 |
xwsstreamevents类型
数据消息按 Begin、零个或多个 Data、End 流式发布,不拼接完整消息。 回调视图只在当前同步调用期间有效,全部事件在传输所属 Worker 上串行执行。
| 字段 | 类型 | 语义 |
|---|---|---|
MessageBegin | void (*MessageBegin)( xwsstream* pStream, const xwsmessageinfo* pInfo, ptr pData ) | 消息开始(含元信息) |
MessageData | void (*MessageData)( xwsstream* pStream, xbytesview Data, ptr pData ) | 消息分片 |
MessageEnd | void (*MessageEnd)(xwsstream* pStream, ptr pData) | 消息结束 |
Pong | void (*Pong)( xwsstream* pStream, xbytesview Payload, ptr pData ) | 收到 Pong |
Backpressure | void (*Backpressure)( xwsstream* pStream, size_t iPending, ptr pData ) | 发送占用越过高水位 |
Writable | void (*Writable)( xwsstream* pStream, size_t iPending, ptr pData ) | 发送占用落回 |
Drain | void (*Drain)(xwsstream* pStream, ptr pData) | 发送队列排空 |
Close | void (*Close)( xwsstream* pStream, const xwsstreamclose* pClose, ptr pData ) | 流关闭(含 Close 帧信息) |
xwsstream类型
WebSocket 流对象(不透明):组合传输上的帧/消息层,绑定所属 Worker。 不透明句柄或别名;生命周期与所有权见各使用方 API 节。
xrtWsStreamConfigInit函数
初始化流层默认配置。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pConfig | 输出 | 非空 | 接收配置 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 无 | 已初始化 | — |
- 无 — 初始化不失败
xrtWsStreamConfigValid函数
校验流层配置自洽。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pConfig | 输入 | 非空 | 待校验配置 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 是自洽 | — |
false | 不是自洽 | — |
- 无 — 纯校验,不设置错误
xrtWsStreamAttach函数
在已就绪的 TCP 流上挂接 WebSocket 流层。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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 流层。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pTransport | 输入 | 非空 | 传输 TLS 流 |
iPrefix | 输入 | — | 前缀已消费字节 |
pConfig | 输入 | 允许空 | 流配置 |
pEvents | 输入 | 允许空 | 事件表 |
pData | 输入 | 任意值 | 用户数据 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | WebSocket 流(引用 1) | — |
NULL | 挂接失败 | XERR_ARGUMENT 等 |
XERR_ARGUMENT— 指针为空或参数非法XERR_STATE— 传输流非开放状态XERR_MEMORY— 分配失败
xrtWsStreamRef函数
增加流引用并返回原指针。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 原指针,引用 +1 | — |
NULL | 参数非法 | XERR_ARGUMENT |
XERR_ARGUMENT— 指针为空或参数非法
xrtWsStreamDestroy函数
释放流引用;关闭必须另行请求。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 允许空 | 空 = 空操作 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 无 | 引用 -1 | — |
- 无 — 释放不失败
xrtWsStreamSend函数
按操作码发送原始帧载荷。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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函数
按操作码压缩发送帧载荷。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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函数
零复制发送帧载荷,离开队列时执行释放过程。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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 分配的载荷并发送。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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 文本消息。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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 文本消息。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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函数
零复制发送文本消息。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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— 握手未完成或已关闭
xrtWsStreamTextTake函数
接管 XRT 分配的文本并发送。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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函数
发送二进制消息。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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函数
压缩发送二进制消息。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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函数
零复制发送二进制消息。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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— 握手未完成或已关闭
xrtWsStreamBinaryTake函数
接管 XRT 分配的数据并发送。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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 控制帧。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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 控制帧。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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 帧并进入关闭握手。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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函数
暂停接收新数据。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 无 | 已暂停 | — |
XERR_ARGUMENT— 指针为空或参数非法
xrtWsStreamResume函数
恢复接收并唤醒所属 Worker。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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函数
返回流当前生命周期状态。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 状态枚举值 | 当前状态 | — |
XERR_ARGUMENT— 指针为空或参数非法
xrtWsStreamRole函数
返回本端协商角色。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
XWS_ROLE_CLIENT / XWS_ROLE_SERVER | 本端角色 | — |
XERR_ARGUMENT— 指针为空或参数非法
xrtWsStreamProtocol函数
返回协商选中的子协议。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 视图 | 子协议借用 | — |
| 空视图 | 未协商 | 不设错误 |
XERR_ARGUMENT— 指针为空或参数非法
xrtWsStreamDeflate函数
复制本流协商的压缩参数。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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 帧信息。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
pClose | 输出 | 非空 | 接收关闭描述 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已复制 | — |
false | 未收到 Close | 不设错误 |
- 未收到 Close 帧返回
false且不设置错误
xrtWsStreamError函数
返回导致流终止的借用错误。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | 终止原因借用 | — |
NULL | 正常关闭或未终止 | 不设错误 |
- 无错误 — 正常关闭或未终止返回
NULL且不设置错误
xrtWsStreamAbort函数
立即丢弃发送队列并异常关闭。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 已关闭 | — |
false | 状态非法 | XERR_STATE |
XERR_ARGUMENT— 指针为空或参数非法XERR_STATE— 已关闭
xrtWsStreamPending函数
返回发送队列占用字节数。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
>= 0 | 占用字节数 | — |
XERR_ARGUMENT— 指针为空或参数非法
范例已编译验证
stream_tour · 发送占用
while ( (xrtWsStreamPending(Client.pStream) != 0u) ||
(xrtWsStreamPending(Server.pStream) != 0u) ) {
xrtWsStreamWritable函数
返回剩余发送预算。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
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函数
判断是否处于暂停状态。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
true | 是暂停 | — |
false | 不是暂停 | — |
XERR_ARGUMENT— 指针为空或参数非法
范例已编译验证
stream_tour · 暂停查询
if ( !xrtWsStreamPaused(Client.pStream) || !exampleRun(pEngine, &Job, Server.pStream, exampleAfterTask) ) goto Cleanup;
xrtWsStreamWorker函数
返回流所属的借用 Worker。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | Worker 借用 | — |
NULL | 参数非法 | XERR_ARGUMENT |
XERR_ARGUMENT— 指针为空或参数非法
xrtWsStreamTcp函数
返回底层 TCP 流借用(不增引用)。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | TCP 流借用 | — |
NULL | 非 TCP 传输 | 不设错误 |
- 非 TCP 挂接返回
NULL且不设置错误
xrtWsStreamTcpRef函数
返回底层 TCP 流并增加引用。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | TCP 流新引用 | — |
NULL | 非 TCP 传输 | 不设错误 |
- 非 TCP 挂接返回
NULL且不设置错误
xrtWsStreamTls函数
返回底层 TLS 流借用(不增引用)。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | TLS 流借用 | — |
NULL | 非 TLS 传输 | 不设错误 |
- 非 TLS 挂接返回
NULL且不设置错误
xrtWsStreamTlsRef函数
返回底层 TLS 流并增加引用。
参数
| 参数 | 方向 | 约束 | 说明 |
|---|---|---|---|
pStream | 输入 | 非空 | 目标流 |
| 返回 | 含义 | 失败时状态 |
|---|---|---|
| 非空 | TLS 流新引用 | — |
NULL | 非 TLS 传输 | 不设错误 |
- 非 TLS 挂接返回
NULL且不设置错误
常量索引常量
以下常量在本页所属头文件中定义,语义见公共头注释。
| 常量 | 说明 |
|---|---|
| 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 | 见头文件注释 |