目录:
第一篇 一个例子
车载消息中间件FastDDS 源码解析(一)FastDDS 介绍和使用
第二篇fastdds的组成
车载消息中间件FastDDS 源码解析(二)RtpsParticipant的创建(上)
车载消息中间件FastDDS 源码解析(三)RtpsParticipant的创建(中)
车载消息中间件FastDDS 源码解析(四)RtpsParticipant的创建(下)
车载消息中间件FastDDS 源码解析(五)BuiltinProtocols(上)
车载消息中间件FastDDS 源码解析(六)BuiltinProtocols(中)EDP
车载消息中间件FastDDS 源码解析(七)BuiltinProtocols(下)WLP&TypeLookupManager
车载消息中间件FastDDS 源码解析(八)TimedEvent
第三篇组网建立连接
pdp建连
车载消息中间件FastDDS 源码解析(十)发送第一条PDP消息(上)
FastDDS 源码解析(十二)发送第一条PDP消息(下)---异步发送
FastDDS 源码解析(十三)发送第一条PDP消息---跨进程发送
FastDDS 源码解析(十六)处理PDP消息——PDP匹配
EDP建连
FastDDS 源码解析(十七)处理PDP消息——EDP匹配
FastDDS 源码解析(十八)EDP阶段发送心跳heartbeat
FastDDS 源码解析(十九)EDP阶段处理heartbeat消息,发送acknack消息
上两篇介绍的内置的协议(EDP,PDP)默认都会配置。 这一篇介绍的协议默认是不会配置的,只是在有需要的时候才会配置。
1.WLP简介:
WLP:
WLP :全称Writer Liveliness Protocol,其实就是和writer 保活相关的协议。我们知道socket 都有心跳来检测网络的稳定性和可靠性,wlp的功能和socket 的心跳机制比较类似,也是管理本地和远端writer状态的协议。当然整个wlp比心跳机制要复杂很多。我们这里只是介绍一下wlp的组成部分。具体的运行机制会在后面详细介绍。
WLP 包含 一个StatefulWriter(RTPSPARTICIPANT_MESSAGE_WRITER 简称 RTPSMsgWriter,对应的就是wlp的mp_builtinWriter属性) 和 一个StatefulReader (RTPSPARTICIPANT_MESSAGE_READER 简称 RTPSMsgReader,对应的就是wlp的mp_builtinReader属性)两个节点。
1.1WLP时序图
sequenceDiagram
participant BuiltinProtocols
Participant WLP
Participant LivelinessManager
participant RTPSParticipantImpl
participant StatefulWriter
Participant StatefulReader
participant NetworkFactory
participant UDPTransportInterface
participant UDPSenderResource
BuiltinProtocols ->> BuiltinProtocols: 1.initBuiltinProtocols()
BuiltinProtocols ->> WLP: 2.new wlp
BuiltinProtocols ->> WLP: 3.initWL
WLP ->> LivelinessManager: 4.new LivelinessManager
WLP ->> WLP: 5.createEndpoints
WLP ->> RTPSParticipantImpl: 6.createWriter()
RTPSParticipantImpl->> RTPSParticipantImpl: 7.create_writer()
RTPSParticipantImpl ->> StatefulWriter: 8.new
RTPSParticipantImpl->> RTPSParticipantImpl: 9.createSendResources()
RTPSParticipantImpl->>NetworkFactory: 10.build_send_resources()
NetworkFactory->>UDPTransportInterface: 11.OpenOutputChannel()
UDPTransportInterface->>UDPTransportInterface: 12.OpenAndBindUnicastOutputsocket()
UDPTransportInterface->>UDPSenderResource: 13.new UDPSenderResource()
RTPSParticipantImpl->> RTPSParticipantImpl: 14.createAndAssociateReceiverswithEndpoint()
RTPSParticipantImpl->>WLP: return statefulWriter
WLP ->> RTPSParticipantImpl: 15.createReader()
RTPSParticipantImpl ->> RTPSParticipantImpl: 16.create_reader()
RTPSParticipantImpl ->> StatefulReader: 17.new
RTPSParticipantImpl->>NetworkFactory: 18.build_send_resources()
NetworkFactory->>UDPTransportInterface: 19.OpenOutputChannel()
UDPTransportInterface->>UDPTransportInterface: 20.OpenAndBindUnicastOutputsocket()
UDPTransportInterface->>UDPSenderResource: 21.new UDPSenderResource()
RTPSParticipantImpl->> RTPSParticipantImpl: 22.createAndAssociateReceiverswithEndpoint()
RTPSParticipantImpl->>WLP: return statefulReader
1.BuiltinProtocols 调用initBuiltinProtocols()
2.initBuiltinProtocols() new 了一个wlp
3.wlp调用initWL
主要干了3件事
创建了pub_liveliness_manager_ 见4
创建了sub_liveliness_manager_ 见4
调用WLP::createEndpoints 创建 reader 和writer 见5
4.new LivelinessManager
5.WLP::createEndpoints
创建了StatefulWriter 见6 StatefulReade 见15
6-14.创建 StatefulWriter 可以看一下 之前创建StatefulWriter章节内容,比较类似
15-22.创建Statefulreader 可以看一下 之前创建Statefulreader章节内容,比较类似
1.2WLP源码
WLP::WLP(
BuiltinProtocols* p)
-----省略部分代码
{
-----省略部分代码
automatic_instance_handle_.value[15] = AUTOMATIC_LIVELINESS_QOS + 0x01;
manual_by_participant_instance_handle_.value[15] = MANUAL_BY_PARTICIPANT_LIVELINESS_QOS + 0x01;
}
这里面有两个关键参数 AUTOMATIC_LIVELINESS_QOS 和 MANUAL_BY_PARTICIPANT_LIVELINESS_QOS。
livelinessqospolicy的参数配置
typedef enum LivelinessQosPolicyKind : fastrtps::rtps::octet
{
/**
* The infrastructure will automatically signal liveliness for the DataWriters at least as often as required by the lease_duration.
*/
AUTOMATIC_LIVELINESS_QOS,
/**
* The Service will assume that as long as at least one Entity within the DomainParticipant has asserted its liveliness the other
* Entities in that same DomainParticipant are also alive.
*/
MANUAL_BY_PARTICIPANT_LIVELINESS_QOS,
/**
* The Service will only assume liveliness of the DataWriter if the application has asserted liveliness of that DataWriter itself.
*/
MANUAL_BY_TOPIC_LIVELINESS_QOS
} LivelinessQosPolicyKind;
AUTOMATIC_LIVELINESS_QOS 自动的通过DataWriter发送liveliness的消息,发送的间隔小于lease_duration,消息通过WLP的端点发送
MANUAL_BY_PARTICIPANT_LIVELINESS_QOS 如果一个PARTICIPANT包含1个或者多个DataWriter,有这个qos,则participant会发送liveness的消息,这个也是通过wlp 的端点发送
AUTOMATIC_LIVELINESS_QOS 和 MANUAL_BY_PARTICIPANT_LIVELINESS_QOS 可以同时运行,就是说这两类liveliness消息,是分别发送的。
比如一个participant 有一个writer 有AUTOMATIC_LIVELINESS_QOS 这个qos,另一个writer有MANUAL_BY_PARTICIPANT_LIVELINESS_QOS这个qos,那么会有2个liveness的消息周期性的发送。
MANUAL_BY_TOPIC_LIVELINESS_QOS 这个并不由WLP 发送,这个是由writer 发送hearbeat message,heartbeat message中将final flag 和 liveliness的flag 设置一下
Livelinessqos 一般设置3个参数,
kind 类型,就是上面介绍的三个类型,默认一般是AUTOMATIC_LIVELINESS
lease_duration,这个一般是无限大,
announcement_period,就是发送周期,这个一般< 0.7*lease_duration
默认的话,lease_duration,这个一般是无限大,其实就是liveliness qos不会开启
LivelinessQosPolicy 类有三个参数
//! Liveliness kind <br> By default, AUTOMATIC_LIVELINESS.
LivelinessQosPolicyKind kind;
/*! Period within which liveliness should be asserted.
* On a DataWriter it represents the period it commits to signal its liveliness.
* On a DataReader it represents the period without assertion after which a DataWriter is considered
* inactive.
* By default, c_TimeInfinite.
*/
fastrtps::Duration_t lease_duration;
/*! The period for automatic assertion of liveliness.
* Only used for DataWriters with AUTOMATIC liveliness.
* By default, c_TimeInfinite.
*
* @warning When not infinite, must be < lease_duration, and it is advisable to be less than 0.7*lease_duration.
*/
fastrtps::Duration_t announcement_period;
这是3个关键参数 kind 执行什么策略,lease_duration这个是多长时间一个writer 需要发送消息来告知其他节点,writer还存在。超过这个时间没有收到消息,表示writer已经下线了。announcement_period表示发送消息的周期,多长时间需要有消息发出来。
这里先对这些参数做个简单的介绍,具体如何运行之后详细深入研究。
步骤3:
bool WLP::initWL(
RTPSParticipantImpl* p)
{
EPROSIMA_LOG_INFO(RTPS_LIVELINESS, "Initializing Liveliness Protocol");
mp_participant = p;
pub_liveliness_manager_ = new LivelinessManager(
[&](const GUID_t& guid,
const LivelinessQosPolicyKind& kind,
const Duration_t& lease_duration,
int alive_count,
int not_alive_count) -> void
{
//这个是到livelinessmanager 中TimedEvent被触发的callback
pub_liveliness_changed(
guid,
kind,
lease_duration,
alive_count,
not_alive_count);
},
mp_participant->getEventResource(),
false);
sub_liveliness_manager_ = new LivelinessManager(
[&](const GUID_t& guid,
const LivelinessQosPolicyKind& kind,
const Duration_t& lease_duration,
int alive_count,
int not_alive_count) -> void
{
sub_liveliness_changed(
guid,
kind,
lease_duration,
alive_count,
not_alive_count);
},
mp_participant->getEventResource());
bool retVal = createEndpoints();
#if HAVE_SECURITY
if (retVal && p->is_secure())
{
retVal = createSecureEndpoints();
}
#endif // if HAVE_SECURITY
return retVal;
}
//主要干了三件事
1.创建了pub_liveliness_manager_ 主要是管理本地的writer
2.创建了sub_liveliness_manager_ 主要是管理remote 的writer
3.创建了Endpoints 就是wlp的 writer 和 reader
步骤4:
LivelinessManager::LivelinessManager(
const LivelinessCallback& callback,
ResourceEvent& service,
bool manage_automatic)
: callback_(callback)
, manage_automatic_(manage_automatic)
, writers_()
, mutex_()
, col_mutex_()
, timer_owner_(nullptr)
, timer_(
service,
[this]() -> bool
{
return timer_expired();
},
0)
{
}
这里初始化了一个TimedEvent,在这个TimedEvent:timer_ 触发的时候(就是lose liveness 的时候)会调用 timer_expired函数
bool LivelinessManager::timer_expired()
{
std::unique_lock<std::mutex> lock(mutex_);
if (timer_owner_ == nullptr)
{
EPROSIMA_LOG_ERROR(RTPS_WRITER, "Liveliness timer expired but there is no writer");
return false;
}
else
{
timer_owner_->status = LivelinessData::WriterStatus::NOT_ALIVE;
}
auto guid = timer_owner_->guid;
auto kind = timer_owner_->kind;
auto lease_duration = timer_owner_->lease_duration;
lock.unlock();
if (callback_ != nullptr)
{
callback_(guid, kind, lease_duration, -1, 1);
}
if (calculate_next())
{
lock.lock();
if ( timer_owner_ != nullptr)
{
// Some times the interval could be negative if a writer expired during the call to this function
// Once in this situation there is not much we can do but let asio timers expire inmediately
auto interval = timer_owner_->time - steady_clock::now();
timer_.update_interval_millisec((double)duration_cast<milliseconds>(interval).count());
return true;
}
}
return false;
}
主要干了2件事
1.调用callback_在这儿就是 WLP::pub_liveliness_changed, 这个函数统计lossliveliness 的次数,回调告知上层应用lossliveliness
2.选出最近会lossliveliness的writer,重新设置timer,如此循环往复
步骤5:
createEndpoints 就是创建WLP的Writer 和 Reader
bool WLP::createEndpoints()
{
const RTPSParticipantAttributes& pattr = mp_participant->getRTPSParticipantAttributes();
const ResourceLimitedContainerConfig& participants_allocation = pattr.allocation.participants;
// Built-in writer history
HistoryAttributes hatt;
set_builtin_writer_history_attributes(hatt, false);
mp_builtinWriterHistory = new WriterHistory(hatt);
PoolConfig writer_pool_cfg = PoolConfig::from_history_attributes(hatt);
payload_pool_ = TopicPayloadPoolRegistry::get("DCPSParticipantMessage", writer_pool_cfg);
payload_pool_->reserve_history(writer_pool_cfg, false);
// Built-in writer
WriterAttributes watt;
watt.endpoint.unicastLocatorList = mp_builtinProtocols->m_metatrafficUnicastLocatorList;
watt.endpoint.multicastLocatorList = mp_builtinProtocols->m_metatrafficMulticastLocatorList;
watt.endpoint.external_unicast_locators = mp_builtinProtocols->m_att.metatraffic_external_unicast_locators;
watt.endpoint.ignore_non_matching_locators = pattr.ignore_non_matching_locators;
watt.endpoint.remoteLocatorList = mp_builtinProtocols->m_initialPeersList;
watt.matched_readers_allocation = participants_allocation;
watt.endpoint.topicKind = WITH_KEY;
watt.endpoint.durabilityKind = TRANSIENT_LOCAL;
watt.endpoint.reliabilityKind = RELIABLE;
RTPSWriter* wout;
if (mp_participant->createWriter(
&wout,
watt,
payload_pool_,
mp_builtinWriterHistory,
nullptr,
c_EntityId_WriterLiveliness,
true))
{
mp_builtinWriter = dynamic_cast<StatefulWriter*>(wout);
EPROSIMA_LOG_INFO(RTPS_LIVELINESS, "Builtin Liveliness Writer created");
}
else
{
EPROSIMA_LOG_ERROR(RTPS_LIVELINESS, "Liveliness Writer Creation failed ");
delete(mp_builtinWriterHistory);
mp_builtinWriterHistory = nullptr;
payload_pool_->release_history(writer_pool_cfg, false);
return false;
}
// Built-in reader history
set_builtin_reader_history_attributes(hatt, participants_allocation, false);
mp_builtinReaderHistory = new ReaderHistory(hatt);
PoolConfig reader_pool_cfg = PoolConfig::from_history_attributes(hatt);
payload_pool_->reserve_history(reader_pool_cfg, true);
// WLP listener
mp_listener = new WLPListener(this);
// Built-in reader
ReaderAttributes ratt;
ratt.endpoint.topicKind = WITH_KEY;
ratt.endpoint.durabilityKind = TRANSIENT_LOCAL;
ratt.endpoint.reliabilityKind = RELIABLE;
ratt.expectsInlineQos = true;
ratt.endpoint.unicastLocatorList = mp_builtinProtocols->m_metatrafficUnicastLocatorList;
ratt.endpoint.multicastLocatorList = mp_builtinProtocols->m_metatrafficMulticastLocatorList;
ratt.endpoint.external_unicast_locators = mp_builtinProtocols->m_att.metatraffic_external_unicast_locators;
ratt.endpoint.ignore_non_matching_locators = pattr.ignore_non_matching_locators;
ratt.endpoint.remoteLocatorList = mp_builtinProtocols->m_initialPeersList;
ratt.matched_writers_allocation = participants_allocation;
ratt.endpoint.topicKind = WITH_KEY;
RTPSReader* rout;
if (mp_participant->createReader(
&rout,
ratt,
payload_pool_,
mp_builtinReaderHistory,
(ReaderListener*)mp_listener,
c_EntityId_ReaderLiveliness,
true))
{
mp_builtinReader = dynamic_cast<StatefulReader*>(rout);
EPROSIMA_LOG_INFO(RTPS_LIVELINESS, "Builtin Liveliness Reader created");
}
else
{
EPROSIMA_LOG_ERROR(RTPS_LIVELINESS, "Liveliness Reader Creation failed.");
delete(mp_builtinReaderHistory);
mp_builtinReaderHistory = nullptr;
delete(mp_listener);
mp_listener = nullptr;
payload_pool_->release_history(reader_pool_cfg, true);
return false;
}
return true;
}
上面函数配置参数创建 mp_builtinReader 和 mp_builtinWriter也就是WLP的Writer 和Reader
1.3类图
classDiagram
WLP *-- StatefulWriter
WLP *-- StatefulReader
WLP *-- LivelinessManager
WLP *-- TimedEvent
class WLP {
+StatefulWriter mp_builtinWriter
+StatefulReader mp_builtinReader
+LivelinessManager pub_liveliness_manager
+LivelinessManager sub_liveliness_manager
+TimedEvent manual_liveliness_assertion
+TimedEvent automatic_liveliness_assertion
}
class StatefulReader {
}
class StatefulWriter {
}
class LivelinessManager {
}
class TimedEvent {
}
WLP 主要功能是两个:
1.一个是定期发送消息,这个automatic_liveliness_assertion 和 manual_liveliness_assertion 负责
这是WLP两个关键的TimedEvent
automatic_liveliness_assertion 对应的 LivelinessQosPolicyKind 是 AUTOMATIC_LIVELINESS_QOS ,定期通过wlp的StatefulWriter类型的mp_builtinWriter发送Liveliness的消息。
manual_liveliness_assertion 对应的 LivelinessQosPolicyKind 是 MANUAL_BY_PARTICIPANT_LIVELINESS_QOS,定期通过wlp的StatefulWriter类型的mp_builtinWriter发送Liveliness的消息。
这两类消息类型是不一样的,在发送端是完全无关的。
2.检查和管理writer的状态。这个由pub_liveliness_manager_ 和sub_liveliness_manager_ 来负责,当发现writer 失去liveliness的时候通过回调函数通知上层应用。timer_ 就负责这个事情。
pub_liveliness_manager 这个是participant 内部 writer状态的管理者 sub_liveliness_manager 这个是participant 匹配的远端 writer状态的管理者
2.TypeLookupManager
2.1简介
TypeLookupManager 其实是为了动态类型而准备的一个对象,是可配置的。
我们如果在收发两端都约定好了数据类型,那么不需要TypeLookupManager。我们发送和接收消息的时候需要这个数据类型用来序列化和反序列化消息。
如果我们并没有约定好数据类型,需要TypeLookupManager来传递类型信息。
一般情况下我们都是使用静态类型,就是收发两端提前约定好了类型。动态类型用的不是太多。所以这个TypeLookupManager是可配置的。默认情况下并不会使用到TypeLookupManager。
2.2时序图
sequenceDiagram
participant BuiltinProtocols
participant TypeLookupManager
participant RTPSParticipantImpl
participant StatefulWriter
participant StatefulReader
BuiltinProtocols ->> TypeLookupManager: 1.TypeLookupManager
BuiltinProtocols ->> TypeLookupManager: 2.init_typelookup_service
TypeLookupManager ->> TypeLookupManager: 3.create_endpoints
TypeLookupManager ->> RTPSParticipantImpl: 4.createWriter
RTPSParticipantImpl ->> RTPSParticipantImpl: 5.create_writer
RTPSParticipantImpl ->> StatefulWriter: 6.new
TypeLookupManager ->> RTPSParticipantImpl:7.createReader
RTPSParticipantImpl ->> RTPSParticipantImpl:8.create_reader
RTPSParticipantImpl ->> StatefulReader: 9.new
- BuiltinProtocols创建TypeLookupManager对象
- BuiltinProtocols调用TypeLookupManager 的init_typelookup_service 初始化TypeLookupManager
- 在初始化TypeLookupManager 的过程中,create_endpoints,就是创建TypeLookupManager的endpoint,也就是StatefulWriter 和StatefulReader
- 在create_endpoints 函数中调用RTPSParticipantImpl 的 create_edp_writer
- RTPSParticipantImpl的createWriter函数 调用自己的create_writer函数
- 最终new了一个StatefulWriter
7,8,9类似 创建了一个StatefulReader
2.3源码解析
步骤1:new TypeLookupManager
没什么太多内容。
步骤2:init_typelookup_service
bool TypeLookupManager::init_typelookup_service(
RTPSParticipantImpl* participant)
{
EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Initializing TypeLookup Service");
participant_ = participant;
bool retVal = create_endpoints();
return retVal;
}
主要是调用了create_endpoints
步骤3:
bool TypeLookupManager::create_endpoints()
{
const RTPSParticipantAttributes& pattr = participant_->getRTPSParticipantAttributes();
// Built-in history attributes.
----
watt.endpoint.reliabilityKind = fastrtps::rtps::RELIABLE;
watt.endpoint.durabilityKind = fastrtps::rtps::VOLATILE;
// Built-in request writer
if (builtin_protocols_->m_att.typelookup_config.use_client)
{
builtin_request_writer_history_ = new WriterHistory(hatt);
RTPSWriter* req_writer;
if (participant_->createWriter(
&req_writer,
watt,
builtin_request_writer_history_,
nullptr,
fastrtps::rtps::c_EntityId_TypeLookup_request_writer,
true))
{
builtin_request_writer_ = dynamic_cast<StatefulWriter*>(req_writer);
EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Builtin Typelookup request writer created.");
}
------
}
// Built-in reply writer
if (builtin_protocols_->m_att.typelookup_config.use_server)
{
builtin_reply_writer_history_ = new WriterHistory(hatt);
RTPSWriter* rep_writer;
if (participant_->createWriter(
&rep_writer,
watt,
builtin_reply_writer_history_,
nullptr,
fastrtps::rtps::c_EntityId_TypeLookup_reply_writer,
true))
{
builtin_reply_writer_ = dynamic_cast<StatefulWriter*>(rep_writer);
EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Builtin Typelookup reply writer created.");
}
------
}
------
ratt.endpoint.reliabilityKind = fastrtps::rtps::RELIABLE;
ratt.endpoint.durabilityKind = fastrtps::rtps::VOLATILE;
// Built-in request reader
if (builtin_protocols_->m_att.typelookup_config.use_server)
{
request_listener_ = new TypeLookupRequestListener(this);
builtin_request_reader_history_ = new ReaderHistory(hatt);
RTPSReader* req_reader;
if (participant_->createReader(
&req_reader,
ratt,
builtin_request_reader_history_,
request_listener_,
fastrtps::rtps::c_EntityId_TypeLookup_request_reader,
true))
{
builtin_request_reader_ = dynamic_cast<StatefulReader*>(req_reader);
EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Builtin Typelookup request reader created.");
}
-----
}
// Built-in reply reader
if (builtin_protocols_->m_att.typelookup_config.use_client)
{
reply_listener_ = new TypeLookupReplyListener(this);
builtin_reply_reader_history_ = new ReaderHistory(hatt);
RTPSReader* rep_reader;
if (participant_->createReader(
&rep_reader,
ratt,
builtin_reply_reader_history_,
reply_listener_,
fastrtps::rtps::c_EntityId_TypeLookup_reply_reader,
true))
{
builtin_reply_reader_ = dynamic_cast<StatefulReader*>(rep_reader);
EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Builtin Typelookup reply reader created.");
}
------
}
return true;
}
主要是创建了1个writer,1个reader
TypeLookupManager 可以配置为client或者server
配置为client的话,会创建 一个Request_Writer和一个Reply_Reader,
配置为server的话,会创建一个Request_Reader和一个Reply_Writer。
2.4类图
classDiagram
TypeLookupManager *-- StatefulWriter
TypeLookupManager *-- StatefulReader
class TypeLookupManager {
+StatefulWriter builtin_request_writer_
+StatefulWriter builtin_reply_writer_
+StatefulReader builtin_reply_reader_
+StatefulReader builtin_request_reader_
}
class StatefulReader {
}
class StatefulWriter {
}
TypeLookupManager如果配置为client的话,会创建 一个Request_Writer和一个Reply_Reader,如果配置为server的话,会创建一个Request_Reader和一个Reply_Writer。
classDiagram
RTPSParticipantImpl *-- BuiltinProtocols
BuiltinProtocols *-- PDP
PDP *-- RTPSWriter
PDP *-- RTPSReader
BuiltinProtocols *-- WLP
PDP *-- EDP
EDP <-- EDPSimple
EDPSimple *--StatefulWriter
EDPSimple *--StatefulReader
BuiltinProtocols *-- TypeLookupManager
class RTPSParticipantImpl {
+BuiltinProtocols mp_builtinProtocols
}
class BuiltinProtocols {
+PDP mp_PDP
+WLP mp_WLP
+TypeLookupManager tlm_
}
class PDP {
+EDP mp_EDP
}
class RTPSWriter {
}
class RTPSReader {
}
class EDPSimple {
std::pair<StatefulWriter*,WriterHistory*> publications_writer_
std::pair<StatefulWriter*,WriterHistory*> subscriptions_writer_
std::pair<StatefulReader*,ReaderHistory*> publications_reader_
std::pair<StatefulReader*,ReaderHistory*> subscriptions_reader_
}
这是完整的BuiltinProtocols的类图,主要包含 PDP EDP WLP TypeLookupManager,他们都有自己的RTPSWriter 和 RTPSReader
总结:这一篇主要介绍WLP 和 TypeLookupManager 我们通过3篇博客,把内置协议都介绍了一下。
下面两篇介绍一下fastdds 中两个关键的对象 TimedEvent 和 Message
目录:
第一篇 一个例子
车载消息中间件FastDDS 源码解析(一)FastDDS 介绍和使用
第二篇fastdds的组成
车载消息中间件FastDDS 源码解析(二)RtpsParticipant的创建(上)
车载消息中间件FastDDS 源码解析(三)RtpsParticipant的创建(中)
车载消息中间件FastDDS 源码解析(四)RtpsParticipant的创建(下)
车载消息中间件FastDDS 源码解析(五)BuiltinProtocols(上)
车载消息中间件FastDDS 源码解析(六)BuiltinProtocols(中)EDP
车载消息中间件FastDDS 源码解析(七)BuiltinProtocols(下)WLP&TypeLookupManager
车载消息中间件FastDDS 源码解析(八)TimedEvent
第三篇组网建立连接
pdp建连
车载消息中间件FastDDS 源码解析(十)发送第一条PDP消息(上)
FastDDS 源码解析(十二)发送第一条PDP消息(下)---异步发送
FastDDS 源码解析(十三)发送第一条PDP消息---跨进程发送
FastDDS 源码解析(十六)处理PDP消息——PDP匹配
EDP建连
FastDDS 源码解析(十七)处理PDP消息——EDP匹配
FastDDS 源码解析(十八)EDP阶段发送心跳heartbeat