1. 概述
本文原英文文章地址:design/request_response_communication.md
除了Iceoryx最初支持的发布-订阅消息模式外,请求-响应模式在Iceoryx所面向的领域中也被广泛使用。由于我们旨在与ROS 2进行良好集成,因此也需要支持其Service
通信方法,该方法通常用于控制机器人。
发布-订阅是一种数据分发模式,它会不断地提供数据更新,而请求-响应则是一种远程过程调用和任务分发模式,仅在需要时提供数据。这意味着有一个或多个客户端请求服务器执行任务。
在Iceoryx中,客户端和服务器将基于我们已经用于发布-订阅的相同构建块构建,如ChunkSender
和ChunkReceiver
。
2. 术语
名称 | 描述 |
---|---|
请求-响应 | 按需提供数据的通信模式 |
发布-订阅 | 不断提供数据更新的通信模式 |
RPC | 远程过程调用,将任务卸载给服务器 |
客户端 | 调用RPC的实体 |
服务器 | 处理RPC的实体 |
3. 设计
3.1 考虑事项
客户端和服务器应能够与WaitSet
和Listener
结合使用,以提供基于事件的通信手段,而不是轮询。
与发布-订阅一样,ServiceDescription
将用于将客户端连接到相应的服务器。
为了支持异步请求,每个请求应包含一个序列ID,该ID将被复制到相应的响应中。
3.2 解决方案
这是无类型Client
和Server
类的概述。
Client
和Server
重用了ChunkSender
和ChunkReceiver
构建块。Client
使用ChunkSender
发送请求并使用ChunkReceiver
获取响应,而Server
使用ChunkReceiver
获取请求并使用ChunkSender
发送响应。
类型化API
由于Response
与特定的Request
绑定,loan
方法会接受一个Request
以使用正确的设置填充Response
。或者,Request
可以有一个createResponse
方法,返回具有正确设置的Response
。
无类型API
与类型化API类似,loan
接受一个指向RequestHeader
的指针,以使用正确的设置填充ResponseHeader
。
客户端端口
ClientPortData
位于共享内存中,仅包含数据而不包含访问方法。ClientPortUser
是为用户提供访问方法的类,ClientPortRouDi
提供了RouDi需要的接口,以便将客户端连接到服务器并清理端口资源。
服务器端口
与客户端端口类似,服务器端口有ServerPortData
,它位于共享内存中,仅包含数据而不包含访问方法。ServerPortUser
是为用户提供访问方法的类,ServerPortRouDi
提供了RouDi需要的接口,以便在服务器提供服务后将客户端连接到服务器,并清理端口资源。
必须确保在任何时候只能有一个具有给定ServiceDescription
的服务器运行。
请求/响应头
由于请求和响应需要编码不同的元信息,我们也需要不同的消息头。公共数据聚合在RpcBaseHeader
中,它包含一个指向ClientChunkQueueData_t
的iox::UniqueId
和一个序列ID。iox::UniqueId
用于标识接收响应的队列,并用作ChunkDistributor::deliverToQueue
的标识符。此方法将遍历所有存储的队列,并匹配ChunkQueueData::m_uniqueIdOfOwner
。作为优化,lastKnownQueueIndex
将用于快速查找,并在队列ID不匹配时降级为完整查找。
class ChunkDistributor {
...
iox::expected<Error> deliverToQueue(iox::UniqueId uniqueQueueId, uint32_t lastKnownQueueIndex, mepoo::SharedChunk chunk);
...
};
序列ID用于在异步调用多个请求时将响应与特定请求匹配。根据客户端和服务器的选项,请求可能会被丢弃,或者服务器可能有一个工作池,从而导致响应的发送顺序与请求的接收顺序不同。序列ID必须由用户设置,并在响应时由用户检查。
客户端/服务器选项
客户端和服务器选项可用于控制客户端和服务器的某些方面。除了设置队列的容量和定义客户端是否应在创建时连接以及服务器是否应在创建时提供服务,还可以定义对慢速客户端和服务器的行为。客户端可以要求服务器在其响应队列已满时阻塞。如果相应的clientTooSlowPolicy
设置为ConsumerTooSlowPolicy::WAIT_FOR_CONSUMER
,服务器将遵守。如果选项不匹配,客户端将无法连接到服务器,这与发布者和订阅者的行为类似。
客户端服务发现
客户端由以下状态机引导。
类似于订阅者状态机,客户端通过CONNECT
CaPro消息将其响应队列传递给服务器。服务器通过ACK
CaPro消息将其请求队列传递给客户端。
以下是显示所有这些情况的序列图
4. 未解决的问题
- 集成到端口自省中
- 集成到网关中,例如DDS网关