1 传输层梳理
1.1 框架
2 使用传输层
2.1 域参与者的三个属性
// 域参与者的三个属性
class RTPSParticipantImpl{
// 1 创建和配置 Transport
NetworkFactory m_network_Factory;
// Transport 接受处理相关
std::list<ReceiverControlBlock> m_receiverResourcelist;
// Transport 发送处理相关
std::vector<std::unique_ptr<fastrtps::rtps::SenderResource>> send_resource_list_;
};
2.1.1 NetworkFactory m_network_Factory;
初始化 Transport
// 1 RTPSParticipantAttributes 记录TransportDescriptor,然后在 创建 RTPSParticipantImpl 时,从用户配置或者环境变量初始化 userTransports
// set_builtin_transports_from_env_var -> attr.setup_transports -> setup_transports_default -> att.userTransports.push_back(descriptor);
class RTPSParticipantAttributes{
std::vector<std::shared_ptr<fastdds::rtps::TransportDescriptorInterface>> userTransports; // TransportDescriptor 数组
};
// 2 同时 创建 RTPSParticipantImpl 时,遍历 m_att.userTransports, 使用 TransportDescriptor 创建具体的 Transport
class NetworkFactory {
std::vector<std::unique_ptr<fastdds::rtps::TransportInterface>> mRegisteredTransports; // Transport 数组
};
for (const auto &transportDescriptor : m_att.userTransports) {
m_network_Factory.RegisterTransport(...){
std::unique_ptr<TransportInterface> transport(descriptor->create_transport());
mRegisteredTransports.emplace_back(std::move(transport));
}
}
2.1.2 std::list m_receiverResourcelist;
// 1 ReceiverControlBlock的内部
struct ReceiverControlBlock {
std::shared_ptr<ReceiverResource> Receiver; // 只负责接收数据
MessageReceiver *mp_receiver; // 按功能处理接收数据 ReceiverResource::OnDataReceived() -> MessageReceiver::processCDRMsg();
}
ReceiverResource::OnDataReceived(...){
rcv->processCDRMsg(remoteLocator, localLocator, &msg);
}
// 2 如何产生1个监听功能
// 2.1 在创建 RTPSParticipantImpl 的时候,会对attr的多播和单播locator 创建1个 ReceiverResource 和 1个 MessageReceiver, 然后组成ReceiverControlBlock 添加到 m_receiverResourcelist
cRTPSParticipantImpl::RTPSParticipantImpl(){
createReceiverResources(m_att.builtin.metatrafficMulticastLocatorList, true, false, true){
std::vector<std::shared_ptr<ReceiverResource>> newItemsBuffer;
m_network_Factory.BuildReceiverResources(*it_loc, newItemsBuffer, max_receiver_buffer_size){
std::shared_ptr<ReceiverResource> newReceiverResource = std::shared_ptr<ReceiverResource>(new ReceiverResource(*transport, local, max_recv_buffer_size));
returned_resources_list.push_back(newReceiverResource);
}
for (auto it_buffer = newItemsBuffer.begin(); it_buffer != newItemsBuffer.end(); ++it_buffer) {
m_receiverResourcelist.emplace_back(*it_buffer);
auto mr = new MessageReceiver(this, (*it_buffer)->max_message_size());
m_receiverResourcelist.back().mp_receiver = mr;
}
}
}
// 2.2 ReceiverResource初始化会创建1个 UDPChannelResource, UDPChannelResource会开启1个线程监听socket,然后有数据就会调用ReceiverResource::OnDataReceived();
ReceiverResource::ReceiverResource(...){
mValid = transport.OpenInputChannel(locator, this, max_message_size_){
success = OpenAndBindInputSockets(locator, receiver, IPLocator::isMulticast(locator), maxMsgSize){
p_channel_resource = CreateInputChannelResource(sInterface, locator, is_multicast, maxMsgSize, receiver){
new UDPChannelResource(...){
auto fn = [this, locator]() {
perform_listen_operation(locator);
};
thread(create_thread(fn, thread_config, "dds.udp.%u", locator.port));
}
}
}
}
}
2.1.3 fastdds::rtps::SendResourceList send_resource_list_;
using SendResourceList = std::vector<std::unique_ptr<fastrtps::rtps::SenderResource>>;
// 创建1个发送相关的类,会创建所有传输层的 具体的实现传输的类,例如UDPSenderResource, 最后把 UDPSenderResource 添加到 send_resource_list_;
RTPSParticipantImpl::createSenderResources(const Locator_t &locator){
m_network_Factory.build_send_resources(send_resource_list_, locator){
for (auto &transport : mRegisteredTransports) {
returned_value |= transport->OpenOutputChannel(sender_resource_list, locator){
sender_resource_list.emplace_back(static_cast<SenderResource *>(new UDPSenderResource(*this, unicastSocket, false, true)));
}
}
}
}
2.2 从上到下流程
// 创建1个域参与者 RTPSDomain类
RTPSParticipantAttributes PParam;
PParam.builtin.discovery_config.discoveryProtocol = eprosima::fastrtps::rtps::DiscoveryProtocol::SIMPLE;
PParam.builtin.use_WriterLivelinessProtocol = true;
mp_participant = RTPSDomain::createParticipant(0, PParam);
// 实际调用 RTPSDomainImpl::createParticipant(...)
RTPSParticipant* RTPSDomain::createParticipant(
uint32_t domain_id,
const RTPSParticipantAttributes& attrs,
RTPSParticipantListener* listen)
{
return RTPSDomainImpl::createParticipant(domain_id, true, attrs, listen);
}
// RTPSDomainImpl::createParticipant 流程
// 核心为 pimpl = new RTPSParticipantImpl(...)
RTPSParticipant *RTPSDomainImpl::createParticipant(...) {
// 1 leaseDuration 检查
// 2 对系统环境初始化
// 3 给 RTPSDomainImpl 生成 guid
// 4 创建 RTPSParticipant 和 RTPSParticipantImpl
// 5 发现协议是 clent-server 模式检查
// 6 pimpl->enable();
}
// RTPSParticipantImpl::RTPSParticipantImpl() 主要流程
RTPSParticipantImpl::RTPSParticipantImpl(...){
// 1 从系统环境初始化 attr, 默认会产生1个 UDPv4TransportDescriptor
// set_builtin_transports_from_env_var -> attr.setup_transports -> setup_transports_default -> att.userTransports.push_back(descriptor);
// 2 发现协议是 clent-server 模式检查
// 3 遍历 attr.userTransports, 初始化每1个传输层
// 4 初始化 ResourceEvent mp_event_thr
// 5 对每1个传输层的过滤检查
// 6 给每个传输层初始化 metatraffic 的 mult_locator 和 uni_locator
// 7 创建接受资源,默认创建 upd socket 并开启监听线程
// createReceiverResources(...)
// m_network_Factory.BuildReceiverResources(...)
// new ReceiverResource(*transport, local, max_recv_buffer_size));
// transport.OpenInputChannel(locator, this, max_message_size_);
// OpenAndBindInputSockets(...)
// CreateInputChannelResource(...)
// new UDPChannelResource(...)
// UDPChannelResource被创建后,会启动1个监听socket线程
while (alive()) {
// 接受socket数据
Receive(...)
// 处理数据
message_receiver()->OnDataReceived(...)
}
}
312

被折叠的 条评论
为什么被折叠?



