鸿蒙NEXT跨设备通信:掌握URPC,实现远程程序调用

在万物互联的时代,如何让设备之间像调用本地方法一样简单地进行远程调用?鸿蒙NEXT的URPC技术正是答案。

在智能设备日益普及的今天,多设备协同工作已经成为一种常见需求。想象一下,你可以用手机控制家里的智能电视播放视频,或在平板电脑上查看和编辑电脑上的文档。

这些场景都离不开跨设备的进程间通信(IPC)和远程过程调用(RPC)技术。

什么是URPC?

URPC(Unified Remote Procedure Call)是鸿蒙NEXT系统中跨设备通信的核心技术,它基于分布式软总线构建,让开发者能够像调用本地方法一样调用远程设备的方法。

URPC与IPC的区别

  • IPC :使用Binder驱动,用于设备内的跨进程通信

  • URPC :使用软总线驱动,用于跨设备跨进程通信

URPC的核心概念与工作原理

在URPC通信模型中,主要包含三个核心角色:

  • 客户端(Proxy):服务请求方,负责发送远程调用请求。

  • 服务端(Stub):服务提供方,接收并处理客户端的请求。

  • 系统能力管理者(SAMgr):管理系统能力(System Ability),协调Proxy和Stub之间的通信。

通信流程类似于构建一座无形的桥梁,将不同的智能设备连接在一起,实现信息的自由流通:

  1. Stub端向SAMgr注册系统能力

  2. Proxy端从SAMgr获取Stub端的代理对象

  3. Proxy通过代理对象向Stub发送请求

  4. Stub处理请求并返回结果给Proxy

环境准备与配置

开发环境要求

  • DevEco Studio版本:NEXT Developer Beta1及以上

  • HarmonyOS SDK版本:NEXT Developer Beta1 SDK及以上

  • 支持设备:华为手机(标准系统)

权限配置

entry/src/main/config.json中申请必要的分布式权限:

json

复制代码
{
  "reqPermissions": [
    {
      "name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE",
      "reason": "用于监听分布式组网内设备状态变化"
    },
    {
      "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO",
      "reason": "用于获取分布式组网内设备列表和信息"
    },
    {
      "name": "ohos.permission.DISTRIBUTED_DATASYNC",
      "reason": "用于不同设备间的数据交换"
    }
  ]
}

依赖配置

在模块的CMakeLists.txthvigorfile.ts中添加URPC依赖:

text

复制代码
# IPC场景
external_deps = ["ipc:ipc_single"]

# RPC场景  
external_deps = ["ipc:ipc_core"]

# 公共基础库
external_deps = ["c_utils:utils"]

实现URPC通信的详细步骤

1. 定义通信接口

首先需要创建一个接口类,继承IRemoteBroker,定义描述符、业务函数和消息码。

cpp

复制代码
#include "iremote_broker.h"

// 定义消息码
const int TRANS_ID_PING_ABILITY = 1;
const std::string DESCRIPTOR = "test.ITestAbility";

class ITestAbility : public IRemoteBroker {
public:
    // DECLARE_INTERFACE_DESCRIPTOR是必需的
    DECLARE_INTERFACE_DESCRIPTOR(to_utf16(DESCRIPTOR));
    
    // 定义业务函数
    virtual int TestPingAbility(const std::u16string &dummy) = 0;
};

2. 实现服务端(Stub)

Stub端作为接收请求的一端,需要继承IRemoteStub并重写OnRemoteRequest方法。

cpp

复制代码
#include "iability_test.h"
#include "iremote_stub.h"

class TestAbilityStub : public IRemoteStub<ITestAbility> {
public:
    virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, 
                                MessageParcel &reply, MessageOption &option) override;
    int TestPingAbility(const std::u16string &dummy) override;
};

int TestAbilityStub::OnRemoteRequest(uint32_t code,
                                    MessageParcel &data, 
                                    MessageParcel &reply, 
                                    MessageOption &option)
{
    switch (code) {
        case TRANS_ID_PING_ABILITY: {
            std::u16string dummy = data.ReadString16();
            int result = TestPingAbility(dummy);
            reply.WriteInt32(result);
            return 0;
        }
        default:
            return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
    }
}

// 实现具体的业务逻辑
class TestAbility : public TestAbilityStub {
public:
    int TestPingAbility(const std::u16string &dummy) override {
        // 这里实现具体的业务逻辑
        return 0;
    }
};

3. 实现客户端(Proxy)

Proxy端是服务请求方,需要继承IRemoteProxy,实现接口类中的方法。

cpp

复制代码
#include "iability_test.h"
#include "iremote_proxy.h"
#include "iremote_object.h"

class TestAbilityProxy : public IRemoteProxy<ITestAbility> {
public:
    explicit TestAbilityProxy(const sptr<IRemoteObject> &impl);
    int TestPingAbility(const std::u16string &dummy) override;

private:
    static inline BrokerDelegator<TestAbilityProxy> delegator_;
};

TestAbilityProxy::TestAbilityProxy(const sptr<IRemoteObject> &impl)
    : IRemoteProxy<ITestAbility>(impl)
{
}

int TestAbilityProxy::TestPingAbility(const std::u16string &dummy)
{
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    dataParcel.WriteString16(dummy);
    
    int error = Remote()->SendRequest(TRANS_ID_PING_ABILITY, 
                                     dataParcel, replyParcel, option);
    int result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1;
    return result;
}

4. 设备发现与连接

跨设备通信前,需要获取目标设备的NetworkId,这就像是给每个设备分配了一个唯一的身份证号码。

java

复制代码
import ohos.distributedhardware.devicemanager.DeviceManager;
import ohos.distributedhardware.devicemanager.DeviceManagerCallback;
import ohos.distributedhardware.devicemanager.RemoteDevice;

public class CrossDeviceCommunication {
    private DeviceManager deviceManager;
    
    // 获取本地设备信息
    public void getLocalDeviceInfo() {
        try {
            LocalDevice localDevice = deviceManager.getLocalDevice();
            String deviceName = localDevice.getDeviceName();
            String networkId = localDevice.getNetworkId();
            // 使用networkId进行跨设备通信
        } catch (DeviceManagerException e) {
            // 异常处理
        }
    }
    
    // 设备发现回调
    private DeviceManagerCallback deviceManagerCallback = new DeviceManagerCallback() {
        @Override
        public void onDeviceFound(RemoteDevice remoteDevice) {
            // 发现新设备时处理
            String deviceName = remoteDevice.getDeviceName();
            String networkId = remoteDevice.getNetworkId();
        }
    };
}

实际应用场景

智能家居控制

在智能家居场景中,手机可以通过URPC向智能灯光系统发送指令,打开客厅的灯光,营造温馨的氛围。

多设备办公

在办公场景中,团队成员可以使用不同的设备实时共享文档、同步编辑进度,就像大家围坐在同一张办公桌前工作一样。

分布式计算

在多媒体处理场景中,手机可以发送视频文件到性能更强的平板设备进行编码处理,然后返回处理结果。

调试技巧

鸿蒙NEXT提供了强大的跨设备分布式应用调试功能:

  1. 设置断点:在涉及跨设备调用的代码行设置断点

  2. 启动调试:选择"Super App"调试配置,启动跨设备调试会话

  3. 跳转跟踪:当代码执行到跨设备调用时,使用Step Into(F7)自动跳转到被调用设备代码处

注意事项与最佳实践

  1. 数据传输限制:单个设备上跨进程通信时,传输的数据量最大约为1MB,过大的数据量请使用匿名共享内存

  2. 错误处理:所有远程调用都应添加适当的错误处理机制,处理网络异常、设备离线等情况

  3. 安全性考虑:敏感数据在传输前应进行加密处理,确保通信安全

  4. 性能优化:避免在频繁调用的方法中进行大量的数据传输,减少网络开销

总结

鸿蒙NEXT的URPC技术为开发者提供了简单高效的跨设备通信解决方案,大大降低了多设备协同应用的开发难度。通过本篇博客的介绍,相信您已经对URPC的基本概念、实现方法和使用场景有了初步了解。

URPC就像是搭建一座无形的桥梁,将不同的智能设备连接在一起,实现信息的自由流通,让多设备协同工作变得更加简单自然。

随着鸿蒙生态的不断发展,URPC将在更多场景中发挥重要作用,为用户带来真正无缝的多设备体验。

希望本篇博客能帮助您快速上手鸿蒙NEXT的URPC开发,期待看到您创造的精彩多设备应用!

相关推荐
程序员潘Sir4 小时前
鸿蒙应用开发从入门到实战(十七):ArkUI组件List&列表布局
harmonyos·鸿蒙
bst@微胖子6 小时前
鸿蒙实现滴滴出行项目之侧边抽屉栏以及权限以及搜索定位功能
android·华为·harmonyos
yenggd9 小时前
vxlan-bgp-evnp分布式网关配置案例
网络·分布式·华为
Danileaf_Guo17 小时前
华为VXLAN小实验:静态方式手工建立隧道
华为
爱笑的眼睛1121 小时前
深入浅出 HarmonyOS 应用开发:ArkTS 语法精要与实践
华为·harmonyos
IT葛大侠21 小时前
华为S5720配置telnet远程
网络·华为
爱笑的眼睛111 天前
HarmonyOS应用开发深度解析:ArkTS语法精要与UI组件实践
华为·harmonyos
Kisang.1 天前
【HarmonyOS】消息通知
华为·harmonyos