SOME/IP开源库Vsomeip分析4-服务注册过程

前言

前面主要对vsomeip中helloworld程序运行进行了分析,本篇文章主要针对helloworld运行时的服务注册过程进行深入分析。

hello_world_service::offer_service

首先还是从examples/hello_world/hello_world_service.hpp文件开始。

void on_state_cbk(vsomeip::state_type_e _state)
{
	if(_state == vsomeip::state_type_e::ST_REGISTERED)
	{
	// we are registered at the runtime and can offer our service
	// 对应提供服务
		app_->offer_service(service_id, service_instance_id);
	}
}

这里会去调用application的offer_service函数。

application_impl::offer_service

void application_impl::offer_service(service_t _service, instance_t _instance,
        major_version_t _major, minor_version_t _minor) {
    // 先找到对应的routing,然后再继续
    if (routing_)
        routing_->offer_service(client_, _service, _instance, _major, _minor);
}

这里会对应两个offer_service,如果自身进程注册了routing服务的话,这里应该调用的是impl,否则调用的就是proxy了。

routing_manager_proxy::offer_service

我们先来看看proxy的实现。

bool routing_manager_proxy::offer_service(client_t _client,
        service_t _service, instance_t _instance,
        major_version_t _major, minor_version_t _minor) {

    if(!routing_manager_base::offer_service(_client, _service, _instance, _major, _minor)) {
        VSOMEIP_WARNING << "routing_manager_proxy::offer_service,"
                << "routing_manager_base::offer_service returned false";
    }
    {
        std::lock_guard<std::mutex> its_lock(state_mutex_);
        if (state_ == inner_state_type_e::ST_REGISTERED) {
            send_offer_service(_client, _service, _instance, _major, _minor);
        }
        service_data_t offer = { _service, _instance, _major, _minor };
        pending_offers_.insert(offer);
    }
    return true;
}

routing_manager_base里面会先去查询对应的服务信息,如果没有找到,那么创建一个,并将对应的服务信息存储在内存中。

//发送给routing_host执行offer_service
void routing_manager_proxy::send_offer_service(client_t _client,
        service_t _service, instance_t _instance,
        major_version_t _major, minor_version_t _minor) {
    (void)_client;

    byte_t its_command[VSOMEIP_OFFER_SERVICE_COMMAND_SIZE];
    uint32_t its_size = VSOMEIP_OFFER_SERVICE_COMMAND_SIZE
            - VSOMEIP_COMMAND_HEADER_SIZE;

    its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_OFFER_SERVICE;
    std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
            sizeof(client_));
    std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
            sizeof(its_size));
    std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
            sizeof(_service));
    std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
            sizeof(_instance));
    its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major;
    std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor,
            sizeof(_minor));

    {
        std::lock_guard<std::mutex> its_lock(sender_mutex_);
        if (sender_) {
            sender_->send(its_command, sizeof(its_command));
        }
    }
}

本地处理完之后,调用send函数去创建local command,然后发送对应的请求给routing进程。

进入routing进程,stub::on_message,解析相关的参数

void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
        endpoint *_receiver, const boost::asio::ip::address &_destination,
        client_t _bound_client,
        credentials_t _credentials,
        const boost::asio::ip::address &_remote_address,
        std::uint16_t _remote_port) {
...
// offer_service操作
    case VSOMEIP_OFFER_SERVICE:
        if (_size != VSOMEIP_OFFER_SERVICE_COMMAND_SIZE) {
            VSOMEIP_WARNING << "Received a OFFER_SERVICE command with wrong size ~> skip!";
            break;
        }

        std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
                sizeof(its_service));
        std::memcpy(&its_instance,
                &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
                sizeof(its_instance));
        std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
                sizeof(its_major));
        std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5],
                sizeof(its_minor));

        //判断是否允许提供服务
        if (security::get()->is_offer_allowed(its_sender_uid, its_sender_gid,
                its_client, its_service, its_instance)) {
            host_->offer_service(its_client, its_service, its_instance,
                    its_major, its_minor);
        } else {
            VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
                    << " : routing_manager_stub::on_message: isn't allowed to offer "
                    << "the following service/instance " << its_service << "/" << its_instance
                    << " ~> Skip offer!";
        }
        break;
...
}

之后进入到impl::offer_service

bool routing_manager_impl::offer_service(client_t _client,
        service_t _service, instance_t _instance,
        major_version_t _major, minor_version_t _minor,
        bool _must_queue) {
...

    // only queue commands if method was NOT called via erase_offer_command()
    // 如果方法没有通过erase_offer_command()调用,则只队列命令
    if (_must_queue) {
        if (!insert_offer_command(_service, _instance, VSOMEIP_OFFER_SERVICE,
                _client, _major, _minor)) {
            return false;
        }
    }

    // Check if the application hosted by routing manager is allowed to offer
    // offer_service requests of local proxies are checked in rms::on:message
    //检查由路由管理器托管的应用程序是否允许提供本地代理的offer_service请求在rms::on:message中被检查
    //这里主要是检查请求offer_service的服务端,是否可以再这个routing上提供服务
    if (_client == get_client()) {
#ifdef _WIN32
        std::uint32_t its_routing_uid = ANY_UID;
        std::uint32_t its_routing_gid = ANY_GID;
#else
        std::uint32_t its_routing_uid = getuid();
        std::uint32_t its_routing_gid = getgid();
#endif
        //安全检查是否允许提供服务
        if (!security::get()->is_offer_allowed(its_routing_uid, its_routing_gid,
                        _client, _service, _instance)) {
            ...
            erase_offer_command(_service, _instance);
            return false;
        }
    }

    //调用对应的服务处理函数
    if (!handle_local_offer_service(_client, _service, _instance, _major, _minor)) {
        erase_offer_command(_service, _instance);
        return false;
    }

    {
        std::lock_guard<std::mutex> its_lock(pending_sd_offers_mutex_);
        if (if_state_running_) {
            //初始化对应的服务信息,创建对应service的endpoint
            init_service_info(_service, _instance, true);
        } else {
            pending_sd_offers_.push_back(std::make_pair(_service, _instance));
        }
    }

    if (discovery_) {
        std::shared_ptr<serviceinfo> its_info = find_service(_service, _instance);
        if (its_info) {
            //如果打开了服务发现,这里应该是广播对应的服务?
            discovery_->offer_service(its_info);
        }
    }

    {
        std::lock_guard<std::mutex> ist_lock(pending_subscription_mutex_);
        std::set<event_t> its_already_subscribed_events;
        for (auto &ps : pending_subscriptions_) {
            if (ps.service_ == _service
                    && ps.instance_ == _instance
                    && ps.major_ == _major) {
                insert_subscription(ps.service_, ps.instance_,
                        ps.eventgroup_, ps.event_, client_, &its_already_subscribed_events);
            }
        }

        send_pending_subscriptions(_service, _instance, _major);
    }
    stub_->on_offer_service(_client, _service, _instance, _major, _minor);
    on_availability(_service, _instance, true, _major, _minor);
    erase_offer_command(_service, _instance);
    return true;
}

handle_local_offer_service主要是routing进程首先先查询本地服务注册信息,其次会去查询远程的服务信息。

//查询local service表,如果没找到对应的服务信息,那么去查找远程的服务信息,如果都没有,
//新建一个local service信息
bool routing_manager_impl::handle_local_offer_service(client_t _client, service_t _service,
        instance_t _instance, major_version_t _major,minor_version_t _minor) {
    {
        std::lock_guard<std::mutex> its_lock(local_services_mutex_);
        //去local service表里面找对应的服务
        auto found_service = local_services_.find(_service);
        if (found_service != local_services_.end()) {
...

// check if the same service instance is already offered remotely
        //检查如果已经没有被远程服务提供,那么会创建一个service info,
              // 并加入local_service表里
        if (routing_manager_base::offer_service(_client, _service, _instance,
                _major, _minor)) {
            local_services_[_service][_instance] = std::make_tuple(_major,
                    _minor, _client);
        } else {
           ...
            return false;
        }
    }
    return true;
}

//发消息给请求者已经完成了offer service的操作
void routing_manager_stub::on_offer_service(client_t _client,
        service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) {
    if (_client == host_->get_client()) {
        create_local_receiver();
    }

    std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
    routing_info_[_client].second[_service][_instance] = std::make_pair(_major, _minor);
    if (security::get()->is_enabled()) {
        distribute_credentials(_client, _service, _instance);
    }
    inform_requesters(_client, _service, _instance, _major, _minor,
            routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, true);
}
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值