vsomeip 源码分析 2 request_service

request service 源码解析

1、hello_world_client 构造函数

    hello_world_client() :
                    rtm_(vsomeip::runtime::get()),
                    app_(rtm_->create_application())
    {
    }

2、init

2.1 application_impl::init()

核心代码如下:

  1. 从xxx.json获取 client_ 即 5555
  {
      "name":"hello_world_client",
      "id":"0x5555"
  }
client_ = its_configuration->get_id(name_);

2.创建routing_

routing_ = std::make_shared<routing_manager_proxy>(this, client_side_logging_, client_side_logging_filter_);

routing_manager_proxy 构造:
state_(inner_state_type_e::ST_DEREGISTERED),
sender_(nullptr),
receiver_(nullptr),
routing_manager_base 的构造函数,
host_(host), = application_impl
io
(host_->get_io()),
client_(host_->get_client()), 5555
3. routing_的init

   routing_->set_client(client_);
   routing_->init();

先设置 client_ 为 5555

void routing_manager_proxy::init() {
    routing_manager_base::init(std::make_shared<endpoint_manager_base>(this, io_, configuration_));
    {
        std::lock_guard<std::mutex> its_lock(sender_mutex_);
        sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT);
    }
}

init会先执行 基类 routing_manager_base 的 init

void routing_manager_base::init(const std::shared_ptr<endpoint_manager_base>& _endpoint_manager) {
    ep_mgr_ = _endpoint_manager;  // endpoint_manager_base
}

endpoint_manager_base::endpoint_manager_base(routing_manager_base* const _rm,
                                             boost::asio::io_service& _io,
                                             const std::shared_ptr<configuration>& _configuration) :
    rm_(_rm),	// routing_manager_proxy
    io_(_io),
    configuration_(_configuration){

}

sender_ <local_client_endpoint_impl>
(const std::shared_ptr<endpoint_host>& _endpoint_host, = endpoint_manager_base
const std::shared_ptr<routing_host>& _routing_host, = routing_manager_proxy
const endpoint_type& remote, = VSOMEIP_ROUTING_CLIENT
这个sender
用来connect VSOMEIP_ROUTING_CLIENT 即 stub。

2.2 、注册回调函数

     // register a state handler to get called back after registration at the
        // runtime was successful
        app_->register_state_handler(
                std::bind(&hello_world_client::on_state_cbk, this,
                        std::placeholders::_1));

        // register a callback for responses from the service
        app_->register_message_handler(vsomeip::ANY_SERVICE,
                service_instance_id, vsomeip::ANY_METHOD,
                std::bind(&hello_world_client::on_message_cbk, this,
                        std::placeholders::_1));

        // register a callback which is called as soon as the service is available
        app_->register_availability_handler(service_id, service_instance_id,
                std::bind(&hello_world_client::on_availability_cbk, this,
                        std::placeholders::_1, std::placeholders::_2,
                        std::placeholders::_3));

第一个 on_state_cbk 在 sender_ connect 成功后执行 ,内容是request_service
第二个 on_availability_cbk 是 request_service 成功后,发送给server 字符串
第三个 on_message_cbk 是收到 server回复的字符串处理

3 、application_impl::start()

创建线程数量:默认 2

const int io_thread_nice_level = configuration_->get_io_thread_nice_level(name_);

创建dispatch线程

auto its_main_dispatcher = std::make_shared<std::thread>(
                    std::bind(&application_impl::main_dispatch, shared_from_this()));

创建shutdown线程

stop_thread_= std::thread(&application_impl::shutdown, shared_from_this());

3.1、 routing_manager_proxy::start()

void routing_manager_proxy::start() {
    is_started_ = true;
    {
        std::lock_guard<std::mutex> its_lock(sender_mutex_);
        if (!sender_) {
            // application has been stopped and started again
            sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT);
        }
        if (sender_) {
            sender_->start();
        }
    }
}

3.1.1 sender_->start()

执行sender_->start() 即 :

void tcp_client_endpoint_impl::start() {
    connect();
}

然后绑定 connect_cbk ,connect成功会执行

strand_.post(std::bind(&client_endpoint_impl::connect_cbk,
                                shared_from_this(), its_bind_error));

connect_cbk 里有 receive();

        socket_->async_receive(
            boost::asio::buffer(&(*_recv_buffer)[_recv_buffer_size], buffer_size),
            strand_.wrap(
                std::bind(
                    &tcp_client_endpoint_impl::receive_cbk,
                    std::dynamic_pointer_cast< tcp_client_endpoint_impl >(shared_from_this()),
                    std::placeholders::_1,
                    std::placeholders::_2,
                    _recv_buffer,
                    _recv_buffer_size
                )
            )
        );

最后会调用 receive_cbk ,里面会执行:

   its_host->on_message(&(*_recv_buffer)[its_iteration_gap],
                         current_message_size, this,
                         boost::asio::ip::address(),
                         VSOMEIP_ROUTING_CLIENT,
                         std::make_pair(ANY_UID, ANY_GID),
                         remote_address_,
                         remote_port_);

its_host = routing_host_.lock(),上文分析到 routing_host_ = routing_manager_proxy

3.1.2 routing_manager_proxy::on_message()

sender_ connect 到 [VSOMEIP_ROUTING_CLIENT] 后,会收到 回复:
case VSOMEIP_ASSIGN_CLIENT_ACK

void routing_manager_proxy::on_client_assign_ack(const client_t &_client)
{
    if (is_started_) {
           init_receiver();
           if (receiver_) {
               receiver_->start();
               VSOMEIP_INFO << std::hex << "Client " << client_
                   << " (" << host_->get_name()
                   << ") successfully connected to routing  ~> registering..";
               register_application();
           }
}

可见 又创建了一个 receiver_ <local_server_endpoint_impl>
endpoint_host_ = endpoint_manager_base >
routing_host_ = routing_manager_proxy >
local_ = /tmp/vsomeip-5555 >
该 receiver_ 用于监听 client的连接 Listening at /tmp/vsomeip-5555 。

3.1.3 listen accept成功

当 routing_manager_proxy 收到 VSOMEIP_ASSIGN_CLIENT_ACK 之后,会创建 receiver_ 监听 来自server 的 连接。当 有连接到来时,会触发 local_server_endpoint_impl 的 receive_cbk

its_host->on_message(&recv_buffer_[its_start],
                    uint32_t(its_end - its_start), its_server.get(),
                    boost::asio::ip::address(), bound_client_, its_credentials);

会执行 case VSOMEIP_ROUTING_INFO

on_routing_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length);

然后:

host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_REGISTERED));
void application_impl::on_state(state_type_e _state)
{
		if (state_ == state_type_e::ST_REGISTERED) {
			do_register_availability_handler();
		}
		
	    if (has_state_handler) {
        std::lock_guard<std::mutex> its_lock(handlers_mutex_);
        std::shared_ptr<sync_handler> its_sync_handler
            = std::make_shared<sync_handler>([handler, _state]() {
                                                handler(_state);
                                             });
        its_sync_handler->handler_type_ = handler_type_e::STATE;
        handlers_.push_back(its_sync_handler);
        dispatcher_condition_.notify_one();
    }
}

上面代码:do_register_availability_handler 会执行 on_availability_cbk ,因为第一次注册

register_availability_handler{
	        availability_[_service][_instance][_major][_minor] = std::make_pair(
                _handler, false);
}

_minor.second.second = false 因此不会执行 :

        if(service_id == _service && service_instance_id == _instance
                && _is_available) // _is_available = false 

但在 do_register_availability_handler 中执行了:

    availability_[_service][_instance][_major][_minor] = std::make_pair(
            _handler, true);

将 _minor.second.second 置为 true。下次会执行。

上文 its_sync_handler 会被 handlers_.push_back ,会执行:

   void on_state_cbk(vsomeip::state_type_e _state)
    {
        if(_state == vsomeip::state_type_e::ST_REGISTERED)
        {
            // we are registered at the runtime now we can request the service
            // and wait for the on_availability callback to be called
            app_->request_service(service_id, service_instance_id);
        }
    }

4、application_impl::request_service()

执行:

void routing_manager_proxy::request_service(client_t _client,
        service_t _service, instance_t _instance,
        major_version_t _major, minor_version_t _minor)
   {
   	if (sender_) {
            sender_->send(&its_command[0],
                    static_cast<std::uint32_t>(its_size + VSOMEIP_COMMAND_HEADER_SIZE));
        }
   }

调用sender_ 发送。

收到 server的回复后,仍会执行 :routing_manager_proxy::on_message() 中的
case VSOMEIP_ROUTING_INFO
依次执行:

 local_services_[its_service][its_instance] = std::make_tuple(its_major, its_minor, its_client);
 host_->on_availability(its_service, its_instance, true, its_major, its_minor);

将获取到的服务信息,保存到 local_services_ 以及
application_impl :: available_[_service][_instance][_major] = _minor; 中

 auto found_service = availability_.find(_service);
 for (const auto &handler : its_handlers) {
          std::shared_ptr<sync_handler> its_sync_handler =
                  std::make_shared<sync_handler>(
                          [handler, _service, _instance, _is_available]()
                          {
                              handler(_service, _instance, _is_available);
                          });
          its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY;
          its_sync_handler->service_id_ = _service;
          its_sync_handler->instance_id_ = _instance;
          handlers_.push_back(its_sync_handler);

会从 availability_ 查找 handler_ 即 app 注册的 on_availability_cbk ,执行。

5、执行 on_availability_cbk

打包一个message ,如下:

 // The service is available then we send the request
 // Create a new request
 std::shared_ptr<vsomeip::message> rq = rtm_->create_request();
{
  its_request->set_message_type(message_type_e::MT_REQUEST);
}
 // Set the hello world service as target of the request
 rq->set_service(service_id);
 rq->set_instance(service_instance_id);
 rq->set_method(service_method_id);

payload为 std::string str(“World”);
发送 : app_->send(rq);
调用了 routing_ 的send 。

    if (routing_) {
        // in case of requests set the request-id (client-id|session-id)
        if (is_request) {
            _message->set_client(client_);
            _message->set_session(get_session());
        }
        // Always increment the session-id
        (void)routing_->send(client_, _message);
    }

其中 client_ 为 4444

bool routing_manager_base::send(client_t _client,
        std::shared_ptr<message> _message) {
       is_sent = send(_client, its_serializer->get_data(),
                its_serializer->get_size(), _message->get_instance(),
                _message->is_reliable(), get_client(), std::make_pair(ANY_UID, ANY_GID), 0, false); 
}

执行 routing_manager_proxy::send

    if (_size > VSOMEIP_MESSAGE_TYPE_POS) {
        std::shared_ptr<endpoint> its_target;
        if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
            // Request
            service_t its_service = VSOMEIP_BYTES_TO_WORD(
                    _data[VSOMEIP_SERVICE_POS_MIN],
                    _data[VSOMEIP_SERVICE_POS_MAX]);
            client_t its_client = find_local_client(its_service, _instance);
            if (its_client != VSOMEIP_ROUTING_CLIENT) {
                if (is_client_known(its_client)) {
                    its_target = ep_mgr_->find_or_create_local(its_client);
                }
            }
        }

先在local_services_搜索 client ,注意这里搜到的 its_client 为 VSOMEIP_ROUTING_CLIENT
因此创建一个client<local_client_endpoint_impl>
创建成功后,会丢入:
local_endpoints_[_client] = its_endpoint; 该client为 4444
最后send出去:

        if (send) {
            is_sent = send_local(its_target,
                    (command == VSOMEIP_NOTIFY_ONE ? _client : get_client()),
                    _data, _size, _instance, _reliable, command, _status_check);
        }

收到server[4444]的答复后,会触发该endpoint的 receive_cbk 进而进入

void routing_manager_proxy::on_message()

执行case VSOMEIP_SEND

 host_->on_message(std::move(its_message));

其中host_ 为 application_impl
从 members_ 里取出 注册的handler,进行执行。

void application_impl::register_message_handler(service_t _service,
        instance_t _instance, method_t _method, message_handler_t _handler) {
    std::lock_guard<std::mutex> its_lock(members_mutex_);
    members_[_service][_instance][_method] = _handler;
}

6 、上图

在这里插入图片描述

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值