软总线源码分析2: 接口解析之注册服务,发布服务和发现服务

本文深入分析了HarmonyOS软总线的源码,详细讲解了注册服务、发布服务和发现服务的实现流程。软总线基于IPC,采用双向通信,客户端和服务器端维护各自的SoftBusServerProxy和SoftBusClientStub。在注册服务时,客户端将包名和SoftBusClientProxy发送给服务端保存。发布服务时,客户端将服务信息发送到服务端,服务端处理并调用回调。发现服务则类似,客户端发起请求,服务端调用本地方法处理并回调。

软总线系统本身也是基于IPC对外提供服务,即软总线运行在系统进程中,对外提供一个名为SoftBusServer的服务。

但是软总线与IPC系统存在一些区别,即软总线为双向通信系统,所以客户端进程同时会维护一个本地的名为SoftBusClient的服务。即客户端维护SoftBusServerProxy和SoftBusClientStub,软总线维护SoftBusServerStub和SoftBusClientProxy。

接口一—注册服务:SoftbusRegisterService

当客户端进程想要将自己注册到软总线时,便调用ServerIpcRegisterService函数,齐源码如下所示:

static int ServerIpcRegisterService(const char *name, const void *info)
{
    if (g_serverProxy == nullptr) {
        LOG_ERR("softbus server g_serverProxy is nullptr!\n");
        return SOFTBUS_ERR;
    }
    int ret = g_serverProxy->SoftbusRegisterService(name, nullptr);
    if (ret != SOFTBUS_OK) {
        LOG_ERR("ServerIpcRegisterService failed!\n");
        return ret;
    }
    LOG_INFO("softbus server register service success!\n");
    return SOFTBUS_OK;
}

客户端进程使用g_serverProxy保存SoftBusServer的代理对象,其SoftbusRegisterService的函数源码如下:

int32_t SoftBusServerProxy::SoftbusRegisterService(const char *clientPkgName, const sptr<IRemoteObject>& object)
{
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) {
        LOG_ERR("remote is nullptr!");
        return SOFTBUS_ERR;
    }

    MessageParcel data;
    int ret = data.WriteRemoteObject(SoftBusServerProxy::GetRemoteInstance());
    if (!ret) {
        LOG_ERR("SoftbusRegisterService write remote object failed!");
        return SOFTBUS_ERR;
    }
    ret = data.WriteCString(clientPkgName);
    if (!ret) {
        LOG_ERR("SoftbusRegisterService write clientPkgName failed!");
        return SOFTBUS_ERR;
    }

    MessageParcel reply;
    MessageOption option;
    int32_t err = remote->SendRequest(MANAGE_REGISTER_SERVICE, data, reply, option);
    if (err != 0) {
        LOG_ERR("SoftbusRegisterService send request failed!");
        return SOFTBUS_ERR;
    }
    int32_t serverRet = 0;
    ret = reply.ReadInt32(serverRet);
    if (!ret) {
        LOG_ERR("SoftbusRegisterService read serverRet failed!");
        return SOFTBUS_ERR;
    }
    return SOFTBUS_OK;
}

由上述源码可知,客户端进程将自己的应用包名,和调用GetRemoteInstance()后获取的SoftBusClientProxy对象,一起发送给服务端进程。服务端对应的SoftbusRegisterService源码如下:

int32_t SoftBusServer::SoftbusRegisterService(const char *clientPkgName, const sptr<IRemoteObject> &object)
{
    if (object == nullptr) {
        LOG_ERR("RegisterService object is nullptr\n");
        return SOFTBUS_ERR;
    }
    std::lock_guard<std::recursive_mutex> autoLock(clientObjectMapLock_);
    clientObjectMap_.insert(std::pair<std::string, sptr<IRemoteObject>>(clientPkgName, object));

    abilityDeath_ = sptr<IRemoteObject::DeathRecipient>(new (std::nothrow) SoftBusDeathRecipient());
    if (abilityDeath_ == nullptr) {
        LOG_ERR("DeathRecipient object is nullptr\n");
        return SOFTBUS_ERR;
    }
    bool ret = object->AddDeathRecipient(abilityDeath_);
    if (!ret) {
        LOG_ERR("AddDeathRecipient failed\n");
        return SOFTBUS_ERR;
    }
    return SOFTBUS_OK;
}

服务端的处理很简单,就是应用包名和对应客户端进程的SoftBusClientStub对象,保存在一个名为clientObjectMap_的键值库中。

接口二—发布服务:PublishService

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值