协商
NRCP QoS 由 Server 授权。Client 允许在订阅或发布请求中携带期望 QoS,但最终生效的 QoS 必须以 Server 返回的授权结果为准
QoS 协商的结果绑定到一个 Flow 上下文,后续消息通过 channel_id + message_type + flow_epoch 查询该上下文。发送端不能通过在单条消息中自报 QoS 参数来提升能力或绕过限制
FlowQoSGrant
协商成功后,Server 应生成一个 Flow 授权结果。授权结果至少应包含:
channel_id:运行时 Flow 标识;flow_epoch:Flow 版本,用于 QoS 更新、订阅重建和旧消息隔离;reliability:可靠性要求,例如reliable或best_effort;ttl_us:单条消息有效期;liveliness_timeout_us:Flow 活性超时时间;max_rate_hz:最大消息频率;burst_limit:最大突发消息数量;max_bytes_per_sec:最大字节速率;payload_type或schema:该 Flow 承载的载荷类型;expire_at或等价生命周期信息:授权结果的有效期;
具体编码格式由消息结构章节定义;本节只规定语义
Request/Response 型
Request/Response 型消息使用固定 QoS,不需要运行时协商
典型流程:
- Client 发送 Request;
- Server 在请求超时时间内返回 Response 或 Error;
- Client 使用
message_id和related_id关联响应; - 若超过请求超时时间仍未收到响应,Client 判定该请求失败;
这类消息默认使用 QUIC Stream 承载,并采用 reliable 语义。固定 QoS 由协议默认值、接口定义或会话级配置给出
Server Push 型
Server Push 型用于 Client 订阅由 Server 持续发送的数据,例如状态、传感器数据、告警等
典型流程:
- Client 发送 Subscribe Request,携带订阅目标和期望 QoS;
- Server 校验资源、载荷类型和 QoS 可用性;
- Server 返回 Subscribe Response,其中携带最终
FlowQoSGrant; - Client 校验授权结果是否可接受;
- Client 发送
FLOW_SUBSCRIBE_ACK表达接受或拒绝该授权结果; - Server 收到接受结果后启动数据流;
- 双方保存 Flow 上下文,并释放协商过程中的临时资源;
若 Client 不接受 Server 返回的 QoS,应发送 accepted = false 的 FLOW_SUBSCRIBE_ACK。Server 收到后不启动数据流,并释放对应 Flow 资源
Server Push 的后续数据消息必须携带授权结果中的 channel_id 和 flow_epoch。Server 更新 QoS 或重建订阅时,应返回新的授权结果并递增 flow_epoch
Client Push 型
Client Push 型用于 Client 向 Server 持续发布数据,例如调试数据、上行状态、应用侧输入流等
典型流程:
- Client 发送 Publish Request,携带发布目标和目标 QoS;
- Server 校验资源、载荷类型、频率限制和本地策略;
- Server 返回 Publish Response,其中携带最终
FlowQoSGrant; - Client 校验授权结果是否可接受;
- Client 发送
FLOW_PUBLISH_ACK表达接受或拒绝该授权结果; - 若接受,Client 按授权 QoS 启动数据流;
- 若不接受,Server 释放对应 Flow 资源;
- 双方保存或释放对应 Flow 上下文;
Client Push 的每条数据消息都应被 Server 按本地 Flow 上下文校验。若消息的 channel_id、message_type 或 flow_epoch 与授权结果不匹配,Server 应拒绝处理该消息
协商失败
协商可能因为以下原因失败:
- 请求不符合当前版本的连接状态或本地策略;
- 请求的载荷类型不存在或当前不可用;
- 期望 QoS 超过 Server 能力或安全策略;
- 资源不足,无法创建新的 Flow;
- Client 不接受 Server 降级后的 QoS;
FLOW_SUBSCRIBE_ACK或FLOW_PUBLISH_ACK超时,或协商过程被取消;
协商失败时,双方必须释放临时 Flow 资源。若 Server 已分配 channel_id 但协商未完成,该 channel_id 不应进入可用 Flow 表,或者必须标记为未激活状态,避免后续消息误用
QoS 更新
已建立的持续 Flow 允许由 Server 发起 QoS 更新。更新触发条件包括网络状态变化、资源压力、订阅降级或本地策略变化
QoS 更新应产生新的 FlowQoSGrant,并递增 flow_epoch。收到新授权后,双方应使用新 Epoch 处理后续消息。旧 Epoch 的迟到消息应被丢弃,或在明确配置的宽限窗口内处理
QoS 更新不应依赖发送端逐包声明新参数。接收端始终以本地保存的最新授权 Flow 上下文为准
接收端校验
接收端处理任何属于动态 Flow 的消息时,应至少执行以下校验:
channel_id是否存在且处于 Active 状态;message_type是否符合该 Flow 授权;flow_epoch是否匹配当前授权版本;- 载荷类型或 Schema 是否匹配;
- 消息是否已过期;
- Flow 是否超过频率或字节速率限制;
- 本地连接状态是否仍为
CONNECTED; - 本地 Flow 状态是否仍为
ACTIVE;
校验失败的消息不应进入业务处理逻辑。实现必须按严重程度执行处置,处置方式包括丢弃、返回错误、关闭 Flow 或关闭会话