request service 源码解析
1、hello_world_client 构造函数
hello_world_client() :
rtm_(vsomeip::runtime::get()),
app_(rtm_->create_application())
{
}
2、init
2.1 application_impl::init()
核心代码如下:
- 从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;
}