协议层接口
协议层接口用于维护 NRCP 会话、建立 Flow、关闭 Flow、报告错误和执行恢复流程。本节只定义通用报文结构,不定义具体业务 Operation 或业务 Flow
ACK
ACK 使用 ACK Message Type,Payload Codec 为 JSON,related_id 指向被确认消息的 message_id
Payload:
{
"status": "received",
"message": "optional message"
}
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
status | string | 是 | received 或 accepted |
message | string | 否 | 可读说明 |
received 表示消息已收到并解析成功,accepted 表示消息已被协议状态机接受。业务执行结果不由 ACK 表达
Error
Error 使用 ERROR 或 OPERATION_ERROR Message Type,Payload Codec 为 JSON,related_id 指向失败消息的 message_id
Payload:
{
"category": "flow",
"code": "FLOW_NOT_FOUND",
"message": "flow context not found",
"retryable": false,
"recoverable": true,
"details": {}
}
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
category | string | 是 | 错误分类 |
code | string | 是 | 错误码 |
message | string | 否 | 可读说明 |
retryable | bool | 否 | 是否允许按本地策略重试 |
recoverable | bool | 否 | 是否可通过恢复流程处理 |
details | object | 否 | 扩展字段 |
Subscribe Flow
Subscribe Flow 用于 Sub 向 Pub 申请订阅某个 Flow
FLOW_SUBSCRIBE_REQUEST
Payload:
{
"flow_name": "/battery_statuses",
"expected_qos": {
"reliability": "best_effort",
"ttl_us": 200000,
"liveliness_timeout_us": 1000000,
"max_rate_hz": 20,
"burst_limit": 4,
"max_bytes_per_sec": 65536
}
}
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
flow_name | string | 是 | 目标 Flow Name |
expected_qos | object | 否 | Sub 期望 QoS |
FLOW_SUBSCRIBE_RESPONSE
Payload:
{
"accepted": true,
"flow_name": "/battery_statuses",
"channel_id": 16385,
"flow_epoch": 1,
"payload_codec": "raw_binary",
"schema": "BatteryStatus",
"qos_grant": {
"reliability": "best_effort",
"ttl_us": 200000,
"liveliness_timeout_us": 1000000,
"max_rate_hz": 20,
"burst_limit": 4,
"max_bytes_per_sec": 65536
}
}
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
accepted | bool | 是 | 是否接受订阅 |
flow_name | string | 是 | Flow Name |
channel_id | uint16 | 接受时必填 | Server 分配的 Flow Channel ID |
flow_epoch | uint32 | 接受时必填 | Flow 版本 |
payload_codec | string | 接受时必填 | Flow Data 的 Payload Codec |
schema | string | 接受时必填 | Flow Data Schema |
qos_grant | object | 接受时必填 | 最终 QoS Grant |
error | object | 拒绝时必填 | 拒绝原因 |
FLOW_SUBSCRIBE_ACK
Payload:
{
"accepted": true,
"flow_name": "/battery_statuses",
"channel_id": 16385,
"flow_epoch": 1
}
Pub 收到 FLOW_SUBSCRIBE_ACK 后才开始发送 FLOW_DATA
Publish Flow
Publish Flow 用于 Pub 通知 Sub 自己准备发布某个 Flow
FLOW_PUBLISH_REQUEST
Payload:
{
"flow_name": "/cmd_vel",
"payload_codec": "raw_binary",
"schema": "Twist",
"expected_qos": {
"reliability": "best_effort",
"ttl_us": 50000,
"liveliness_timeout_us": 200000,
"max_rate_hz": 50,
"burst_limit": 4,
"max_bytes_per_sec": 65536
}
}
FLOW_PUBLISH_RESPONSE
Payload:
{
"accepted": true,
"flow_name": "/cmd_vel",
"channel_id": 8193,
"flow_epoch": 1,
"qos_grant": {
"reliability": "best_effort",
"ttl_us": 50000,
"liveliness_timeout_us": 200000,
"max_rate_hz": 50,
"burst_limit": 4,
"max_bytes_per_sec": 65536
}
}
FLOW_PUBLISH_ACK
Payload:
{
"accepted": true,
"flow_name": "/cmd_vel",
"channel_id": 8193,
"flow_epoch": 1
}
Pub 发送 ACK 后允许开始发送 FLOW_DATA
Flow Close
Pub 和 Sub 均允许主动关闭 Flow,但必须通过 FLOW_CLOSE 通知对端
Payload:
{
"flow_name": "/cmd_vel",
"channel_id": 8193,
"flow_epoch": 1,
"reason": "UNSUBSCRIBE",
"message": "client stops publishing",
"final_sequence": 4096
}
常见 reason:
NORMAL;UNSUBSCRIBE;PUBLISHER_STOPPED;QOS_NOT_ACCEPTABLE;FLOW_EXPIRED;SESSION_DEGRADED;RATE_LIMITED;PAYLOAD_SCHEMA_CHANGED;INTERNAL_ERROR;
Recovery
RECOVER_REQUEST 由 Client 发起,用于在同一 QUIC 连接上恢复 NRCP 层状态
Payload:
{
"known_flows": [
{
"flow_name": "/battery_statuses",
"channel_id": 16385,
"flow_epoch": 1,
"last_sequence": 2048
}
]
}
RECOVER_RESPONSE Payload:
{
"status": "REBUILD_REQUIRED",
"flows": [
{
"flow_name": "/battery_statuses",
"channel_id": 16385,
"flow_epoch": 2,
"action": "resubscribe"
}
]
}
status 可选值:
RECOVERED;REBUILD_REQUIRED;SESSION_EXPIRED;