fastddsv2.14.1 传输层框架分析

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(...)
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值