请求服务:
client应用:
application_impl::request_service
routing_manager_client::request_service (老版本是routing_manager_proxy)
routing_manager_client::send_request_services
protocol::request_service_command its_command; // 创建订阅cmd
local_uds_client_endpoint_impl::send // 将订阅cmd发送给routingmanagerd
routingmanagerd:
local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的request service命令
routing_manager_stub::on_message
routing_manager_impl::request_service
endpoint_manager_impl::find_or_create_remote_client // 从remote_service_info_中查找远端服务的配置,创建client_endpoint
tcp_client_endpoint_impl::start // 启动线程进行connect操作 (创建并且打开asio socket,设置socket属性,最后async_connect)
udp_client_endpoint_impl::start // 同上
在vsomeip中,每一个服务只占用一个端口(TCP/UDP/BOTH),无论method还是event都在这个端口上通信。
client发给routingmanagerd的cmd中,包含了client的端的clientid
请求事件:
client应用:
application_impl::request_event (service, instance, event, eventgroup事件组集合, 事件类型, reliable) //事件类型event/field/select_event
routing_manager_client::register_event
routing_manager_client::send_register_event
protocol::register_events_command its_command; // 注册event的cmd
local_uds_client_endpoint_impl::send // 将注册event的cmd发送给routingmanagerd
routingmanagerd:
local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的request event命令
routing_manager_stub::on_message
轮询protocol::register_events_command中的每一个register event项目
routing_manager_impl::register_shadow_event
routing_manager_base::register_event //将事件和事件组注册到内部的events_ 和eventgroups_ 中
// routing_manager_base内部events_ 和eventgroups_ 的作用
primitive_types.hpp
...
typedef uint32_t message_t;
typedef uint16_t service_t;
typedef uint16_t method_t;
typedef uint16_t event_t;typedef uint16_t instance_t;
typedef uint16_t eventgroup_t;
...
event.hpp
...
class event {...
private:...// 记录了每个eventgroup有哪些本地client订阅了// 每个event可以属于一个或者多个eventgroupstd::map<eventgroup_t, std::set<client_t> > eventgroups_;...
};
...
eventgroupinfo.hpp
class eventgroupinfo {
...
private:...std::set<std::shared_ptr<event> > events_; // 记录了该eventgroup中的所有event(event中可以找到订阅该eventgroup的client)...std::map<remote_subscription_id_t,std::shared_ptr<remote_subscription>> subscriptions_; // 保存对其他域的服务的订阅者的信息remote_subscription_id_t id_; // 每增加一个对其他域的服务的订阅者(非域内), id_ 加一...
};
routing_manager_base.hpp
std::map<service_t, // 服务IDstd::map<instance_t, // 实例IDstd::map<event_t, // 事件IDstd::shared_ptr<event> > > > events_; // 事件所属的组和每个组的订阅客户端std::map<service_t, // 服务IDstd::map<instance_t,// 实例IDstd::map<eventgroup_t, std::shared_ptr<eventgroupinfo> > > > eventgroups_; // 事件组中的事件和每个事件的订阅者信息
订阅:
client应用:
application_impl::subscribe
routing_manager_client::subscribe
routing_manager_client::send_subscribe
protocol::subscribe_command its_command; // 订阅cmd
local_uds_client_endpoint_impl::send // 将订阅的cmd发送给routingmanagerd
routingmanagerd:
local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的subscribe命令
routing_manager_stub::on_message
routing_manager_impl::subscribe
const client_t its_local_client = find_local_client(_service, _instance); // 获取是哪个client发布了要订阅的服务
// 1. 订阅的服务是当前routingmanagerd应用发布的
if (get_client() == its_local_client) {
endpoint_manager_base::find_or_create_local // 根据订阅者的clientid创建用于通信的local
application_impl::on_subscription // 通知application有订阅到达,是否accept (accept_cbk是传入的匿名函数)
routing_manager_stub::send_subscribe_ack // 接收订阅,则回复ACK
routing_manager_stub::send_subscribe_nack // 否则回复NACK
}
// 2. 订阅的服务不是当前routingmanagerd应用发布的
routing_manager_base::insert_subscription
if (_event != ANY_EVENT) { // subscribe to specific event
// 在event_中插入订阅client的订阅记录
} else {
// 在eventgroups_的每个event中插入订阅client的订阅记录
}
// 2.1 订阅的服务是域外的someip应用发布的
if (0 == its_local_client) { // 说明域内找不到提供该服务的ciient
routing_manager_impl::find_event // 查看是否有client对该event进行过register(调用request_event)
routing_manager_impl::handle_subscription_state //主要是看对该event的订阅是否已经有收到过ACK了
if (its_state->second == subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED) {
// Subscription already acknowledged!
if (_client == get_client()) {
// 如果订阅该服务的是routingmanagerd应用自己,则直接回调
application_impl::on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /OK/);
} else if (stub_) {
// 如果订阅该服务的是域内的其他应用,则通过uds将ACK消息发送过去
routing_manager_stub::send_subscribe_ack(_client, _service, _instance, _eventgroup, _event);
}
}
service_discovery_impl::subscribe // 通过SD模块订阅其他域发布的待订阅service/event/eventgroup
subscribed_.find //查找之前是否订阅过该eventgroup
std::shared_ptr<subscription> its_subscription = create_subscription() // 创建新的订阅
subscribed_[service] [inst] [eventgroup] = its_subscription;
service_discovery_impl::send_subscription
entry_data_t its_data; //创建要订阅的eventgroup的entry (create_eventgroup_entry)
auto its_current_message = std::make_shared<message_impl>(); // 创建要发送的OFFER报文
add_entry_data(its_messages, its_data); // 将订阅的eventgroup entry添加到OFFER报文中 service_discovery_impl::serialize_and_send // 发送
}
// 2.2 订阅的服务是域内其他someip应用发布的
else {
routing_manager_stub::send_subscribe //通过UDS 发送订阅请求给发布该service/Instance的client
}
发布服务:
client应用:
application_impl::offer_service
routing_manager_client::offer_service // 参数中带着clientid以及service的信息
routing_manager_base::offer_service // 判断一下是否可以发布service (例如局域网中已经有别的client发布了相同的service/instance)
routing_manager_client::send_offer_service
protocol::offer_service_command its_offer; // 创建发布服务的cmd
local_uds_client_endpoint_impl::send // 将offer service的cmd发送给routingmanagerd
routingmanagerd:
local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的offer service命令
routing_manager_impl::offer_service
routing_manager_impl::insert_offer_command // 插入OFFER队列 (个人理解用于后期定周期发送)
routing_manager_impl::handle_local_offer_service // 判断是否可以Offer Service (是否存在冲突),可以offer的情况下插入local_services_中
service_discovery_impl::offer_service // 如果collected_offers_中不存在要发布的service,则添加进去
service_discovery_impl::on_offer_debounce_timer_expired // debounce定时器触发,将collected_offers_的offerentry倒出来后清空
std::shared_ptr<message_impl> its_message(std::make_shared<message_impl>()); // 创建要发送出去的Offer报文
service_discovery_impl::insert_offer_entries //将要offer的所有service entry加入Offer报文
service_discovery_impl::insert_offer_service // 添加单个service entry (service的entry以及option,option中包含了用于通信的endpoint信息)
service_discovery_impl::add_entry_data
service_discovery_impl::send // 发送Offer报文
offerservice有三种冲突的情况下,会offer失败:1. local存在相同服务 2. remote发布过相同服务 3. 当前应用本次offer的服务和之前offer的服务存在冲突
处理收到的Offer报文:
routingmanagerd:
routing_manager_impl::on_message
service_discovery_impl::on_message // 需要是SD报文才会给SD模块处理
service_discovery_impl::process_serviceentry // 判断entry’类型是service还是eventgroup的条件是type <= 2
service_discovery_impl::process_offerservice_serviceentry // service entry条目中type=1 (offer Service)
service_discovery_impl::update_request // 如果目前处于repetition阶段,则停止对该service发送FIND报文(因为已经收到了offer了)
if (_received_via_mcast) { // 如果是从组播地址收到的OFFER报文
auto found_service = subscribed_ .find(_service); // 从 subscribed_ 成员中查找本域中是否有client对该服务中事件组的订阅
更新每一条订阅记录的状态
ST_ACKNOWLEDGED -> ST_RESUBSCRIBING
非ST_ACKNOWLEDGED -> ST_RESUBSCRIBING_NOT_ACKNOWLEDGED
}
routing_manager_impl::add_routing_info // 新增/更新serviceinfo信息到services_remote_和services_两个内部容器
std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance)); // 判断是否收到过该service的offer
if (!its_info) { // 没有是收到过该service的offer
routing_manager_base::create_service_info // 创建新的serviceinfo信息,添加到services_以及services_remote_中
}
endpoint_manager_impl::is_remote_service_known // 判断是否在该service上创建endpoint(reliable/unreliable)
if (_reliable_port != ILLEGAL_PORT && !is_reliable_known) { // service提供了tcp端口,对应的endpoint没有创建
for (const client_t its_client : get_requesters_unlocked(
endpoint_manager_impl::find_or_create_remote_client // 创建和service的tcp连接
its_info->add_client(its_client); // 将请求该service的client添加到上面create_service_info创建的serviceinfo中
}
}
if (_unreliable_port != ILLEGAL_PORT && !is_unreliable_known) { // service提供了udp端口,对应的endpoint没有创建
// 逻辑同TCP
}
if (!_reliable_address.is_unspecified() || !_unreliable_address.is_unspecified()) {
// 记录每个远端地址上发布的服务信息和收到的Offer报文数量并且打印
}
client应用:
无:
entry条目类型的枚举值: (enumeration_types.hpp)
enum class entry_type_e: uint8_t {FIND_SERVICE = 0x00,OFFER_SERVICE = 0x01,STOP_OFFER_SERVICE = 0x01,REQUEST_SERVICE = 0x2,FIND_EVENT_GROUP = 0x4,PUBLISH_EVENTGROUP = 0x5,STOP_PUBLISH_EVENTGROUP = 0x5,SUBSCRIBE_EVENTGROUP = 0x06,STOP_SUBSCRIBE_EVENTGROUP = 0x06,SUBSCRIBE_EVENTGROUP_ACK = 0x07,STOP_SUBSCRIBE_EVENTGROUP_ACK = 0x07,UNKNOWN = 0xFF
};
service_discovery_impl中保存的事件组订阅情况的类Subscription主要结构如下:
class subscription {
...
private:std::shared_ptr<endpoint> reliable_;std::shared_ptr<endpoint> unreliable_;bool tcp_connection_established_;bool udp_connection_established_;std::map<client_t, subscription_state_e> clients_; // client-> is acknowledged? // 每个client的订阅状态std::weak_ptr<eventgroupinfo> eg_info_; // 订阅的事件组信息
};
routing_manager_impl中保存的收到的service信息的类serviceinfo主要结构如下:
class serviceinfo {
...
private:service_t service_;instance_t instance_;major_version_t major_;minor_version_t minor_;std::shared_ptr<endpoint> reliable_;std::shared_ptr<endpoint> unreliable_;std::set<client_t> requesters_; // 请求过该服务的本地client
};
服务可用通知(Service Aailable)
routingmanagerd:
client_endpoint_impl::cancel_and_connect_cbk // 作为async_connect的回调函数被调用
client_endpoint_impl::connect_cbk
endpoint_manager_impl::on_connect
routing_manager_impl::service_endpoint_connected
routing_manager_impl::on_availability
routing_manager_stub::on_offer_service // 通知客户端sevice avaliable
routing_manager_stub::inform_requesters // routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE
for (auto its_client : service_requests_) { // 该连接是用于和远端service通信的,找到请求了对应service的本地client
routing_manager_stub::send_client_routing_info
protocol::routing_info_command its_command; // 发送给client的routing_info信息(包含了service信息)
}
client应用:
routing_manager_client::on_message
routing_manager_client::on_routing_info
for (const auto &e : its_command.get_entries()) { // 轮询每一个entry (号到type为RIE_ADD_SERVICE_INSTANCE的条目)
application_impl::on_availability // 通知application服务可用
}
处理订阅:
routingmanagerd:
service_discovery_impl::on_message
auto its_acknowledgement = std::make_shared<remote_subscription_ack>(_sender); //提前准备好给客户端回复的订阅ACK/NACK报文
service_discovery_impl::process_eventgroupentry
service_discovery_impl::insert_subscription_ack
service_discovery_impl::add_entry_data_to_remote_subscription_ack_msg
service_discovery_impl::send_subscription_ack
client应用:
无
处理订阅ACK/NACK
routingmanagerd:
service_discovery_impl::on_message
service_discovery_impl::process_eventgroupentry(
if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == its_type) { // 对于eventgroupentry类型为subscribe_ack/nack
service_discovery_impl::handle_eventgroup_subscription_ack/_nack (根据Entry中的TTL判断是ACK还是NACK)
auto found_service = subscribed_.find(_service);
for (…) { // 找到每一个订阅该eventgroup的client
found_eventgroup->second->set_state(its_client, subscription_state_e::ST_ACKNOWLEDGED); // 修改订阅状态 (ACKED)
routing_manager_impl::on_subscribe_ack(_client)
}
}
client应用:
发布事件:
client应用: