https://datatracker.ietf.org/doc/html/draft-ietf-core-coap-pubsub-09
一、 概述
1. 背景与目标
-
CoAP 协议: 面向资源受限设备(如低功耗无线传感器网络)的机器对机器通信协议,采用请求/响应模型。
- 设备可能同时作为客户端和服务器。
- 某些设备由于电池供电或能量收集机制,大部分时间处于休眠状态,网络连接性有限。
- 某些中间设备(如 NAT、防火墙)也会限制设备的可达性,通常只允许设备主动发起的连接。
-
发布/订阅(Pub/Sub)通信模型:
- 适用于需要多对多通信的场景,通信通过主题(Topic)而非端点进行。
- 发布者无需了解消息的最终接收者,由 Broker 负责匹配订阅和发布,并将消息转发给订阅者。
-
本草案目标:
- 为 CoAP 协议引入简单的扩展,实现基于 Broker 的发布/订阅通信机制。
- 解决资源受限设备在传统请求/响应模型下的通信瓶颈问题。
- 支持节点间断断续续的连接和/或运行时间有限的情况,实现存储转发消息传递。
2. 关键特性
-
Broker 节点:
- 作为 CoAP 服务器,提供 REST API 接口,供客户端进行发布/订阅交互。
- 无需客户端之间直接可达,只需 Broker 对所有客户端可达即可。
- 需要具备足够的资源(存储、带宽等)来托管 CoAP 资源服务,并可能代表客户端缓冲消息。
-
客户端:
- 使用本规范定义的 CoAP pub/sub REST API 与 Broker 交互。
- 数据源(如传感器客户端)可以向 Broker 发布状态更新。
- 数据接收器(如执行器客户端)可以从 Broker 读取或订阅状态更新。
- 应用客户端可以同时使用发布和订阅,与数据源和数据接收器交换状态更新。
二、 架构与概念
1. CoAP Pub/Sub 架构
- Broker: 充当消息代理,托管 pub/sub REST API。
- 客户端: 与 Broker 交互,发布或订阅主题。
- 主题(Topic) :
- 用于标识发布/订阅系统中的特定资源或对象。
- 通常以层次结构形式表示,例如
/sensors/weather/barometer/pressure
。 - 由 Broker 托管,所有使用 Broker 的客户端共享相同的主题命名空间。
- 每个主题都有一个关联的链接,包括 Broker 上的引用路径和链接属性。
- 每个主题可以关联零个或多个存储的表示(representation)和一个在链接中指定的 content-format。
- 主题可以包含一个或多个子主题,形成树状结构。
2. Brokerless Pub/Sub
- 在某些用例中,希望使用 pub/sub 语义进行点对点通信,但不希望或不需要在网络上包含单独的 Broker 节点。
- 在其他用例中,希望实现单向通信,例如传感器向服务推送更新。
- Brokerless 配置 :
- 对等节点系统中的节点可以同时充当 Broker 和客户端。
- 支持 Broker 功能的节点可以预配置公开服务和资源的主题。
- Brokerless 对等节点可以与客户端和 Broker 节点混合使用,实现完全互操作性。
三、 CoAP Pub/Sub REST API
本规范定义了 Broker 向 pub/sub 客户端公开的 REST API,主要包括以下操作:
1. DISCOVERY(发现)
- 目的: 客户端发现 Broker 或主题。
- 方法: GET
- URI 模板 :
/.well-known/core?rt=core.ps
用于发现 Broker。{+ps}/?rt="temperature"
用于发现主题。/.well-known/core?ct=50
也可用于主题发现。
- 响应 :
- 成功: 2.05 Content,包含 application/link-format 负载,包含匹配的资源条目。
- 失败: 4.04 Not Found(未找到)或 4.00 Bad Request(请求格式错误)。
- 示例 :
- 客户端发送 GET 请求到 Broker 的
.well-known/core
位置,查询rt=core.ps
属性以发现 Broker。 - 客户端可以进一步查询主题,例如查找资源类型为 "temperature" 的主题。
- 客户端发送 GET 请求到 Broker 的
2. CREATE(创建主题)
- 目的: 客户端在 Broker 上创建新主题。
- 方法: POST
- URI 模板 :
{+ps}/{+topic}
- 请求负载 :
- 使用 CoRE 链接格式的序列化表示,指定主题 URI 和内容格式(ct)。
- 可选地,可以包含主题的生命周期(Max-Age)。
- 响应 :
- 成功: 2.01 Created,包含新主题的 URI。
- 失败: 4.00 Bad Request(请求格式错误)或 4.01 Unauthorized(未授权)。
- 注意事项 :
- 一次只能创建单个主题。
- 主题字符串中不能包含 "/" 字符。
- 主题创建者应发布初始值,以便在主题可发现后对 READ 和 SUBSCRIBE 请求做出响应。
3. PUBLISH(发布)
- 目的: 客户端向 Broker 发布主题的更新。
- 方法: PUT 或 POST
- URI 模板 :
{+ps}/{+topic}
- 请求负载 :
- 使用指定的内容格式表示主题的值。
- 可选地,可以包含 Max-Age 选项,指示值的最大生命周期。
- 响应 :
- 成功: 2.04 Changed(主题已更新)或 2.01 Created(主题已创建)。
- 失败: 4.00 Bad Request(请求格式错误)、4.01 Unauthorized(未授权)、4.04 Not Found(主题不存在)或 4.29 Too Many Requests(请求过多)。
- 注意事项 :
- 发布操作必须使用主题创建时指定的内容格式。
- Broker 可以选择接受使用 PUT 方法对不存在的主题进行发布操作,并创建该主题。
- Broker 可以选择执行垃圾回收,删除已发送给所有订阅者或已超时的存储表示。
- Broker 至少应保留最近发布的一个表示,以响应 SUBSCRIBE 和 READ 请求。
4. SUBSCRIBE(订阅)
- 目的: 客户端订阅 Broker 上的主题。
- 方法: GET
- 选项: Observe:0
- URI 模板 :
{+ps}/{+topic}
- 响应 :
- 成功: 2.05 Content,包含当前值和 Observe 选项。
- 失败: 4.00 Bad Request(请求格式错误)、4.01 Unauthorized(未授权)、4.04 Not Found(主题不存在)或 4.15 Unsupported Content Format(不支持的内容格式)。
- 通知机制 :
- Broker 使用 CoAP 通知机制(RFC 7641)通知订阅的客户端。
- 每次收到发布时,Broker 都会向所有订阅的客户端发送通知。
- 注意事项 :
- 订阅请求的内容格式必须与主题创建时指定的内容格式匹配。
- 如果主题尚未发布,Broker 可以选择确认并排队挂起的订阅,并在初始发布发生时延迟响应。
5. UNSUBSCRIBE(取消订阅)
- 目的: 客户端取消对 Broker 上主题的订阅。
- 方法: GET
- 选项: Observe:1
- URI 模板 :
{+ps}/{+topic}
- 响应 :
- 成功: 2.05 Content 或 2.07 No Content。
- 失败: 4.00 Bad Request(请求格式错误)、4.01 Unauthorized(未授权)或 4.04 Not Found(主题不存在)。
- 取消机制 :
- 客户端可以使用带有 Observe 参数 1 的 GET 请求取消订阅。
- 或者,客户端可以在收到发布时发送 CoAP 重置消息来取消订阅。
6. READ(读取)
- 目的: 客户端读取 Broker 上主题的当前值。
- 方法: GET
- URI 模板 :
{+ps}/{+topic}
- 响应 :
- 成功: 2.05 Content,包含当前值。
- 失败: 4.00 Bad Request(请求格式错误)、4.01 Unauthorized(未授权)、4.04 Not Found(主题不存在)或 4.15 Unsupported Content Format(不支持的内容格式)。
- 注意事项 :
- 读取请求的内容格式必须与主题创建时指定的内容格式匹配。
- 如果主题尚未发布,Broker 可以选择确认并排队挂起的读取,并在初始发布发生时延迟响应。
7. REMOVE(删除)
- 目的: 客户端删除 Broker 上的主题。
- 方法: DELETE
- URI 模板 :
{+ps}/{+topic}
- 响应 :
- 成功: 2.02 Deleted。
- 失败: 4.00 Bad Request(请求格式错误)、4.01 Unauthorized(未授权)或 4.04 Not Found(主题不存在)。
- 注意事项 :
- 删除主题时,Broker 应移除所有观察者,并返回最终的 4.04 Not Found 响应。
- 如果删除的主题包含子主题,则所有子主题也必须被递归删除。
四、 其他重要内容
1. 与资源目录(Resource Directory)的协作
- Broker 可以将 pub/sub 服务的基 URI 注册到资源目录中,客户端可以使用资源目录发现 Broker。
- 客户端可以将创建的 pub/sub 主题链接注册到资源目录中,以便发现主题。
- Broker 可以触发资源目录从
.well-known/core
检索其链接。
2. 睡眠/唤醒操作
- CoAP pub/sub 允许客户端在操作之间休眠,在空闲期间节省能量。
- Broker 保留来自休眠客户端的最后一个状态更新,以便在响应读取和订阅操作时向其他客户端提供最新的状态更新。
- 同样,Broker 保留主题上接收到的最后一个状态更新,以便休眠客户端在唤醒时可以对 Broker 执行读取操作,以从最新的系统状态更新中更新其自身状态。
3. 简单流量控制
- Broker 节点可能需要为每个发布消息发送大量通知消息,并且可能同时为大量订阅者和发布者提供服务。
- 如果 Broker 收到对流行主题的大量发布消息,可能会不堪重负。
- Broker 可以使用 4.29 Too Many Requests 响应代码来指示客户端在指定时间后重试,并停止为该客户端和主题创建通知。
4. 安全性考虑
- CoAP pub/sub 重用了 CoAP、CoRE 资源目录和 Web 链接,因此这些文档的安全性考虑也适用于本规范。
- Broker 和客户端应相互认证并执行访问控制策略。
- 恶意客户端可能会订阅其无权访问的数据,或通过发布大量资源对 Broker 发起拒绝服务攻击。
- 认证可以使用标准化的 DTLS 提供的机制(例如证书)进行。
- DTLS 还允许建立通信安全,以确保交换数据的完整性和机密性。
- 端到端安全性对于某些场景是必要的,例如传感器网络上的客户端设备与云服务器基础设施上运行的客户端应用程序之间的通信。
- 建议使用应用层安全性,例如对象安全(OSCORE)。
- 当只需要端到端加密且 CoAP Broker 受信任时,可以使用仅保护负载(PAYL)模式。
五、 总结
本草案为 CoAP 协议引入了基于 Broker 的发布/订阅机制,旨在解决资源受限设备在传统请求/响应模型下的通信瓶颈问题,并支持设备间断断续续的连接和/或运行时间有限的情况。 它详细定义了 Broker 提供的 REST API 接口、主题管理机制、订阅/取消订阅流程以及与资源目录的协作方式,并考虑了流量控制和安全性等问题。