8. Multicast CoAP
CoAP 支持向 IP 组播组发起请求. 这是通过相对于单播 CoAP 的一系列差异来定义的. 关于使用 CoAP 进行组通信的更一般讨论见 [GROUPCOMM].
提供服务并希望其他端点能够通过组播服务发现找到这些服务的 CoAP 端点, 会加入一个或多个适当的 all-CoAP-node 组播地址 (Section 12.8), 并在默认 CoAP 端口上监听. 注意, 端点可能会在其他组播地址上收到组播请求, 包括 all-nodes IPv6 地址 (或通过 IPv4 广播). 因此, 端点 MUST 准备好接收此类报文, 但如果不需要组播服务发现, MAY 忽略它们.
8.1. 消息层
组播请求的特征是: 它承载在一个发往 IP 组播地址而不是 CoAP 端点的 CoAP 报文中. 这样的组播请求 MUST 是 Non-confirmable.
服务器 SHOULD 能够知道某个请求是通过组播到达的, 例如在可用时使用 IPV6_RECVPKTINFO [RFC3542] 这样的现代 API.
为了避免错误响应激增, 当服务器知道请求是通过组播到达时, 它 MUST NOT 针对 Non-confirmable 报文返回 Reset 报文. 如果服务器不知道这一点, 它 MAY 像通常一样针对 Non-confirmable 报文返回 Reset 报文. 由于这样的 Reset 报文看起来与发送方的单播报文所对应的 Reset 报文完全相同, 发送方 MUST 避免使用仍在该端点与任何可能接收该组播报文的单播端点之间处于活动状态的 Message ID.
在撰写本文时, 组播报文只能承载在 UDP 中, 不能承载在 DTLS 中. 这意味着本文档为 CoAP 定义的 security mode 不适用于组播.
8.2. 请求/响应层
当服务器知道某个请求是通过组播到达时, 服务器 MAY 始终忽略该请求, 尤其是在它没有任何有用内容可响应时 (例如, 只有空 payload 或错误响应). 该决定可能取决于应用. (例如, 在 [RFC6690] 中描述的查询过滤中, 如果过滤器不匹配, 服务器不应响应组播请求. 更多示例见 [GROUPCOMM].)
如果服务器确实决定响应组播请求, 它不应立即响应. 相反, 它应选择一个时间段, 表示它打算在该时间段内进行响应. 为了便于说明, 我们把这个时间段的长度称为 Leisure. 该 Leisure 的具体值可能取决于应用, 或 MAY 按如下方式推导. 随后服务器 SHOULD 在所选 leisure period 内随机选择一个时间点, 向组播请求发送单播响应. 如果需要基于同一组播地址成员关系发送更多响应, 新的 leisure period 最早在前一个结束之后开始.
为了计算 Leisure 值, 服务器应有一个组大小估计 G, 一个目标数据传输速率 R (二者都应保守选择), 以及一个估计响应大小 S. 然后可以按如下方式计算 Leisure 的粗略下界:
lb_Leisure = S * G / R
例如, 对于 2.4 GHz IEEE 802.15.4 (6LoWPAN) 网络上具有链路本地范围的组播请求, G 可以 (相对保守地) 设为 100, S 设为 100 bytes, 目标速率设为 8 kbit/s = 1 kB/s. 得到的 Leisure 下界为 10 seconds.
如果 CoAP 端点没有合适的数据来计算 Leisure 值, 它 MAY 使用 DEFAULT_LEISURE.
在将响应与组播请求匹配时, 只有 token MUST 匹配. 响应的源端点不需要 (也不会) 与原始请求的目标端点相同.
为了诠释 Location-* options 以及表示中嵌入的任何链接, request URI (即用于解释响应的 base URI) 通过将原始 request URI 的 Host 组件中的组播地址替换为实际响应端点的字面 IP 地址来形成.
8.2.1. 缓存
当客户端发出组播请求时, 它总是向组播组发起一个新的请求 (因为期间可能有新的组成员加入, 或者某些成员没有收到前一个请求). 它 MAY 用收到的响应更新缓存. 然后, 它把仍然新鲜的缓存响应和新的响应都作为该请求的结果使用.
对发往组播组的 GET 请求所收到的响应 MAY 用于满足随后针对相关单播 request URI 的请求. 该单播 request URI 通过将 request URI 的 authority 部分替换为响应报文的传输层源地址而获得.
缓存 MAY 通过在相关单播 request URI 上发起 GET 请求来重新验证响应.
发往组播组的 GET 请求 MUST NOT 包含 ETag option. 用于抑制客户端已有响应的机制留待进一步研究.
8.2.2. 代理
当 forward-proxy 收到一个带有 Proxy-Uri 或由 Proxy-Scheme 构造出的 URI 且该 URI 指示组播地址的请求时, 代理按上述方式获得一组响应, 并将所有响应 (包括仍然新鲜的缓存响应和新的响应) 发送回原始客户端.
本规范没有提供一种方式来在以这种方式转发的响应中指示经单播修改后的 request URI (base URI). 代理组播请求在 [GROUPCOMM] 中有更详细讨论. 关于解决 base URI 问题的一个提案可见 [CoAP-MISC] 的 Section 3.