当前位置: 首页 > news >正文

HarmonyOS 远端状态订阅开发实例

IPC/RPC 提供对远端 Stub 对象状态的订阅机制, 在远端 Stub 对象消亡时,可触发消亡通知告诉本地 Proxy 对象。这种状态通知订阅需要调用特定接口完成,当不再需要订阅时也需要调用特定接口取消。使用这种订阅机制的用户,需要实现消亡通知接口 DeathRecipient 并实现 onRemoteDied 方法清理资源。该方法会在远端 Stub 对象所在进程消亡或所在设备离开组网时被回调。值得注意的是,调用这些接口有一定的顺序。首先,需要 Proxy 订阅 Stub 消亡通知,若在订阅期间 Stub 状态正常,则在不再需要时取消订阅;若在订阅期间 Stub 所在进程退出或者所在设备退出组网,则会自动触发 Proxy 自定义的后续操作。

使用场景

这种订阅机制适用于本地 Proxy 对象需要感知远端 Stub 对象所在进程消亡,或所在设备离开组网的场景。当 Proxy 感知到 Stub 端消亡后,可适当清理本地资源。此外,RPC 目前不提供匿名 Stub 对象的消亡通知,即只有向 SAMgr 注册过的服务才能被订阅消亡通知,IPC 则支持匿名对象的消亡通知。

Native 侧接口

参考代码
 

#include "iremote_broker.h"
#include "iremote_stub.h"//定义消息码
enum {TRANS_ID_PING_ABILITY = 5,TRANS_ID_REVERSED_MONITOR
};const std::string DESCRIPTOR = "test.ITestAbility";class ITestService : public IRemoteBroker {
public:// DECLARE_INTERFACE_DESCRIPTOR是必需的,入参需使用std::u16string;DECLARE_INTERFACE_DESCRIPTOR(to_utf16(DESCRIPTOR));virtual int TestPingAbility(const std::u16string &dummy) = 0; // 定义业务函数
};class TestServiceProxy : public IRemoteProxy<ITestAbility> {
public:explicit TestAbilityProxy(const sptr<IRemoteObject> &impl);virtual int TestPingAbility(const std::u16string &dummy) override;int TestAnonymousStub();
private:static inline BrokerDelegator<TestAbilityProxy> delegator_; // 方便后续使用iface_cast宏
};TestServiceProxy::TestServiceProxy(const sptr<IRemoteObject> &impl): IRemoteProxy<ITestAbility>(impl)
{
}int TestServiceProxy::TestPingAbility(const std::u16string &dummy){MessageOption option;MessageParcel dataParcel, replyParcel;dataParcel.WriteString16(dummy);int error = PeerHolder::Remote()->SendRequest(TRANS_ID_PING_ABILITY, dataParcel, replyParcel, option);int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1;return result;
}
#include "iremote_object.h"class TestDeathRecipient : public IRemoteObject::DeathRecipient {
public:virtual void OnRemoteDied(const wptr<IRemoteObject>& remoteObject);
}void TestDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remoteObject)
{
}
sptr<IPCObjectProxy> object = new IPCObjectProxy(1, to_utf16(DESCRIPTOR));
sptr<IRemoteObject::DeathRecipient> deathRecipient (new TestDeathRecipient());// 构造一个消亡通知对象
bool result = object->AddDeathRecipient(deathRecipient); // 注册消亡通知
result = object->RemoveDeathRecipient(deathRecipient); // 移除消亡通知

JS 侧接口

参考代码

import FA from "@ohos.ability.featureAbility";let proxy;let connect = {    onConnect: function(elementName, remoteProxy) {        console.log("RpcClient: js onConnect called.");        proxy = remoteProxy;    },    onDisconnect: function(elementName) {        console.log("RpcClient: onDisconnect");    },    onFailed: function() {        console.log("RpcClient: onFailed");    }};let want = {    "bundleName": "com.ohos.server",    "abilityName": "com.ohos.server.MainAbility",};FA.connectAbility(want, connect);class MyDeathRecipient {    onRemoteDied() {        console.log("server died");    }}let deathRecipient = new MyDeathRecipient();proxy.addDeathRecipient(deathRecipient, 0);proxy.removeDeathRecipient(deathRecipient, 0);

Stub 感知 Proxy 消亡(匿名 Stub 的使用)

正向的消亡通知是 Proxy 感知 Stub 的状态,若想达到反向的死消亡通知,即 Stub 感知 Proxy 的状态,可以巧妙的利用正向消亡通知。如两个进程 A(原 Stub 所在进程)和 B(原 Proxy 所在进程),进程 B 在获取到进程 A 的 Proxy 对象后,在 B 进程新建一个匿名 Stub 对象(匿名指未向 SAMgr 注册),可称之为回调 Stub,再通过 SendRequest 接口将回调 Stub 传给进程 A 的原 Stub。这样一来,进程 A 便获取到了进程 B 的回调 Proxy。当进程 B 消亡或 B 所在设备离开组网时,回调 Stub 会消亡,回调 Proxy 会感知,进而通知给原 Stub,便实现了反向消亡通知。

注意:

反向死亡通知仅限设备内跨进程通信使用,不可用于跨设备。

当匿名 Stub 对象没有被任何一个 Proxy 指向的时候,内核会自动回收。

参考代码

//Proxyint TestAbilityProxy::TestAnonymousStub(){    MessageOption option;    MessageParcel dataParcel, replyParcel;    dataParcel.UpdateDataVersion(Remote());    dataParcel.WriteRemoteObject(new TestAbilityStub());    int error = Remote()->SendRequest(TRANS_ID_REVERSED_MONITOR,dataParcel, replyParcel, option);    int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1;    return result;}
//Stub
int TestAbilityStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option){    switch (code) {        case TRANS_ID_REVERSED_MONITOR: {            sptr<IRemoteObject> obj = data.ReadRemoteObject();            if (obj == nullptr) {                reply.WriteInt32(ERR_NULL_OBJECT);                return ERR_NULL_OBJECT;            }            bool result = obj->AddDeathRecipient(new TestDeathRecipient());            result ? reply.WriteInt32(ERR_NONE) : reply.WriteInt32(-1);            break;        }        default:            break;    }    return ERR_NONE;}
http://www.lryc.cn/news/191671.html

相关文章:

  • 实战一:Http轮询弹幕拦截
  • 虚拟机独立 IP 配置
  • 升级教育技术软件的多合一解决方案
  • c++视觉检测-----角点检测
  • 虚拟机安装Docker
  • 虚幻引擎5:增强输入的使用方法
  • buffer overflow detected
  • 【c++源码】老飞飞源码完整v15源码(包含数据库前端后端源文件)
  • MySQL创建数据库、创建表操作和用户权限
  • 时间序列分析基础篇
  • Idea JavaWeb项目,继承自HttpFilter的过滤器,启动Tomcat时部署工件出错
  • 02Maven核心程序的下载与settings.xml文件的配置,环境变量的配置
  • 栈实现深度优先搜索
  • Java 基于SpringBoot的某家乡美食系统
  • splice 和 slice 会改变原数组吗? 怎么删除数组最后一个元素?
  • 解锁互联网安全的新钥匙:JWT(JSON Web Token)
  • alsa音频pcm设备之i2c调试
  • 1. Windows平台下如何编译C++版本的Redis库hiredis
  • Centos中利用自带的定时器Crontab_实现mysql数据库自动备份_linux中mysql自动备份脚本---Linux运维工作笔记056
  • 完美解决Android adb install 安装提示 INSTALL_FAILED_TEST_ONLY
  • [清华大学]漏洞挖掘之状态敏感的模糊测试StateFuzz
  • 嵌入式养成计划-40----C++菱形继承--虚继承--多态--模板--异常
  • C++入门指南:类和对象总结友元类笔记(下)
  • ctfshow web入门 php特性 web136-web140
  • sshpass传输文件提示Host key verification failed.
  • Maven系列第5篇:私服详解
  • 深入解析Spring Cloud Gateway的GlobalFilter
  • ffmpeg的重采样计算
  • Go HTTP 调用(上)
  • STM32Cube高效开发教程<基础篇>(一)----概述