0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

详解proxy-stub结构的设计模式

OpenHarmony技术社区 来源:HarmonyOS技术社区 作者:HarmonyOS技术社区 2022-03-30 09:28 次阅读

OpenHarmony 中存在很多的服务,一般来说可以使得 A 应用调用 B 服务的方法,就像在自己进程中调用一样,这里具体的实现实际通过 binder 驱动实现。

binder 驱动通过 mmap 将内核态代码映射到用户态,直接读写数据这样就完成了跨进程的调用。不过这不是该篇内容的重点,本片主要讲一下 proxy - stub 的设计模式。

服务的一般编码模式

使用 proxy - stub 架构编程,大致可以分为以下三个步骤:

设计接口类,继承至 IRemoteBroker,接口方法一般设计为虚方法。

设计 proxy 类,继承至 IRemoteProxy,并且实现 sendRequest 方法和自身虚方法。

设计 stub 类,继承至 IRemoteStub ,并且实现 OnRemote 方法和自身虚方法。

这样我们就可以在调用是调用 proxy 类的接口方法就像调用 stub 类的接口方法一样了。

源码剖析

我们通过阅读源码,解开其神秘的面纱。我们现在关注几个重点的类。

IRemoteObject:

classIRemoteObject:publicvirtualParcelable,publicvirtualRefBase{
public:
enum{
IF_PROT_DEFAULT,/*Invokerfamily.*/
IF_PROT_BINDER=IF_PROT_DEFAULT,
IF_PROT_DATABUS,
};
enum{
DATABUS_TYPE,
};
classDeathRecipient:publicRefBase{
public:
enum{
ADD_DEATH_RECIPIENT,
REMOVE_DEATH_RECIPIENT,
NOTICE_DEATH_RECIPIENT,
TEST_SERVICE_DEATH_RECIPIENT,
TEST_DEVICE_DEATH_RECIPIENT,
};
virtualvoidOnRemoteDied(constwptr&object)=0;
};

virtualint32_tGetObjectRefCount()=0;

virtualintSendRequest(uint32_tcode,MessageParcel&data,MessageParcel&reply,MessageOption&option)=0;

virtualboolIsProxyObject()const;

virtualboolCheckObjectLegality()const;

virtualboolAddDeathRecipient(constsptr&recipient)=0;

virtualboolRemoveDeathRecipient(constsptr&recipient)=0;

virtualboolMarshalling(Parcel&parcel)constoverride;

staticIRemoteObject*Unmarshalling(Parcel&parcel);

staticboolMarshalling(Parcel&parcel,constsptr&object);

virtualsptrAsInterface();

virtualintDump(intfd,conststd::vector<std::u16string>&args)=0;

conststd::u16stringdescriptor_;

std::u16stringGetObjectDescriptor()const;

protected:
explicitIRemoteObject(std::u16stringdescriptor=nullptr);
};

这就是真正在 binder 驱动中数据传输的类,继承自 Parcelable 。而继承RefBase 可以理解为智能指针的控制块。

OpenHarmony 中这里并没有直接使用 C++ 标准库中的智能指针,而是使用 sptr 和 refbase 两个类共同构建,也就是裸指针和控制块相关信息。使用后者的方式,更加解耦。符合复杂架构设计理念。

IRemoteBroker:


classIRemoteBroker:publicvirtualRefBase{
public:
IRemoteBroker()=default;
virtual~IRemoteBroker()override=default;
virtualsptrAsObject()=0;
staticinlinesptrAsImplement(constsptr&object)
{
returnnullptr;
}
};

#defineDECLARE_INTERFACE_DESCRIPTOR(DESCRIPTOR)
staticinlineconststd::u16stringmetaDescriptor_={DESCRIPTOR};
staticinlineconststd::u16string&GetDescriptor()
{
returnmetaDescriptor_;
}

一般的接口类,通过 metaDescriptor_ 作为表示区分标识。

IRemoteProxy:

namespaceOHOS{
template<typenameINTERFACE>classIRemoteProxy:publicPeerHolder,publicINTERFACE{
public:
explicitIRemoteProxy(constsptr&object);
~IRemoteProxy()override=default;

protected:
sptrAsObject()override;
};

template<typenameINTERFACE>
IRemoteProxy::IRemoteProxy(constsptr&object):PeerHolder(object)
{
}

template<typenameINTERFACE>sptrIRemoteProxy::AsObject()
{
returnRemote();
}
}//namespaceOHOS

IRemoteProxy 使用 c++ 的 crtp (奇特重现模板模式)编程,使得父类可以调用子类的方法。继承自 peerhold (其实就是包括一个 IRemoteObject 对象)。

IRemoteStub:



namespaceOHOS{
template<typenameINTERFACE>classIRemoteStub:publicIPCObjectStub,publicINTERFACE{
public:
IRemoteStub();
virtual~IRemoteStub()=default;
sptrAsObject()override;
sptrAsInterface()override;
};

template<typenameINTERFACE>IRemoteStub::IRemoteStub():IPCObjectStub(INTERFACE::GetDescriptor()){}

template<typenameINTERFACE>sptrIRemoteStub::AsInterface()
{
returnthis;
}

template<typenameINTERFACE>sptrIRemoteStub::AsObject()
{
returnthis;
}
}//namespaceOHOS

stub 对象较于 proxy 对象复杂一些,也使用 crtp 编程。会继承 IPCObjectStub(也是 iremoteObject 对象)。

看到这里,可能有人疑惑,为什么 proxy 调用,会直接调用到 stub 这端呢?

其实奥秘就在于 stub 继承的 IPCObjectStub(继承 iremoteObject)对象,就是这个 iremoteObject 对象。

proxy 的构造继承 peerhold,peerhold 类中的iremoteObject 对象和 IPCObjectStub 这个是什么关系呢?

其实 peerhold 是 IPCObjectStub 的引用对象,实际类型是 IPCObjectProxy。

这两者在 ipc 框架中,IPCObjectProxy 实际使用 sendrequest,IPCObjectStub 便会调用 OnremoteRequest。如果有兴趣,我们下次可以分析 IPC 框架具体是如何实现的。

原文标题:剖析鸿蒙经典的proxy - stub架构

文章出处:【微信公众号:HarmonyOS技术社区】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内核
    +关注

    关注

    3

    文章

    1363

    浏览量

    40228
  • 架构
    +关注

    关注

    1

    文章

    509

    浏览量

    25447
  • OpenHarmony
    +关注

    关注

    25

    文章

    3660

    浏览量

    16154

原文标题:剖析鸿蒙经典的proxy - stub架构

文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony技术社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    教你PADS 中如何检查 Stub 线!!!

    此份简明教程将以图文的形式展示如何帮助您快速和准确地进行 DFM 检查和优化 Stub 线。
    的头像 发表于 07-10 15:48 9140次阅读
    教你PADS 中如何检查 <b class='flag-5'>Stub</b> 线!!!

    注册表结构详解

    注册表结构详解
    发表于 03-05 15:06

    连接器过孔stub对信号的影响

    图所示: 图 1过孔结构图下面我们对该过孔进行建模仿真,看看过孔stub到底对信号有什么样的影响,影响有多大。具体内容,看附件。看完的朋友,如果喜欢本文,欢迎在下方留个脚印啊。
    发表于 01-05 18:29

    HarmonyOS远端状态订阅开发实例

    IPC/RPC提供对远端Stub对象状态的订阅机制, 在远端Stub对象消亡时,可触发消亡通知告诉本地Proxy对象。这种状态通知订阅需要调用特定接口完成,当不再需要订阅时也需要调用特定接口取消
    发表于 10-12 14:55

    防火墙术语-Proxy

    防火墙术语-Proxy   英文原义:Proxy 中文释义:代理 注  解:防火墙的一类。工作在应用层,特点是两次连
    发表于 02-24 11:01 1001次阅读

    开关电源拓扑结构详解

    开关电源拓扑结构详解
    发表于 01-14 11:18 74次下载

    一文详解OpenHarmony软总线

    本次说明可能侧重在标准系统之上。软总线依旧采用鸿蒙经典的 proxy - stub 架构,接口类 ISoftBusServer,ISoftBusClient。
    的头像 发表于 03-30 08:38 5576次阅读

    xsec-proxy-scanner代理扫描器

    xsec-proxy-scanner.zip
    发表于 04-28 09:18 5次下载
    xsec-<b class='flag-5'>proxy</b>-scanner代理扫描器

    php-proxy-app Web代理服务器

    php-proxy-app.zip
    发表于 04-29 10:51 1次下载
    php-<b class='flag-5'>proxy</b>-app Web代理服务器

    Tcp-DNS-proxy TCP DNS代理

    Tcp-DNS-proxy.zip
    发表于 04-29 10:44 2次下载
    Tcp-DNS-<b class='flag-5'>proxy</b> TCP DNS代理

    Exchange_proxy Exchange安全代理

    exchange_proxy.zip
    发表于 05-07 09:51 0次下载
    Exchange_<b class='flag-5'>proxy</b> Exchange安全代理

    nginx-proxy Docker容器的自动化nginx代理

    ./oschina_soft/nginx-proxy.zip
    发表于 05-12 11:30 1次下载
    nginx-<b class='flag-5'>proxy</b> Docker容器的自动化nginx代理

    全面解读MOSFET结构及设计详解

    MOSFET结构、特性参数及设计详解
    发表于 01-26 16:47 1294次阅读

    Stub Generator V.1.00 用户手册

    Stub Generator V.1.00 用户手册
    发表于 04-27 19:44 0次下载
    <b class='flag-5'>Stub</b> Generator V.1.00 用户手册

    设计模式结构性:代理模式

    在代理模式Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式
    的头像 发表于 06-09 15:27 819次阅读
    设计<b class='flag-5'>模式</b><b class='flag-5'>结构</b>性:代理<b class='flag-5'>模式</b>