Remote Communication Kit URPC:远程函数调用、弱网传输与多径通信模型【鸿蒙心迹】
调用服务器上的 getUserInfo(),为什么代码写起来像本地函数,底层却走了十万八千里?

做客户端开发的时候,最爽的就是写一行 userApi.getUserInfo(userId),然后就像调用本地函数一样拿到结果。
结果真出问题的时候才发现:这一行函数调用,根本不是本地的。它要把参数序列化、打包、过网络、到服务器、执行、把结果序列化、再传回来。中间任何一步出问题,都是用户看到的"加载失败"。
一、先想清楚:这一行函数调用到底做了什么
先把最基础的问题想明白。
你写的是:
let user = await userApi.getUserInfo(userId);
看起来就是调了一个函数。但实际上,背后发生了这么多事:
| 阶段 | 做什么 |
|---|---|
| 参数序列化 | 把 userId 打包成网络能传的格式 |
| 建立连接 | 跟服务器建立 TCP/UDP 连接 |
| 发送请求 | 把请求包发出去 |
| 服务端执行 | 服务器收到请求,执行业务逻辑 |
| 结果序列化 | 把返回值打包 |
| 返回响应 | 把结果传回来 |
| 反序列化 | 把结果解成你要的对象 |
这一套走下来,可能几十毫秒,也可能几百毫秒。网络不好的时候,可能直接超时。
二、URPC 和普通 HTTP/REST 有什么区别
很多人以为:RPC 不就是换个方式发 HTTP 请求吗?
不对。HTTP/REST 是面向资源的,你请求一个 URL,拿到一个资源。
RPC 是面向方法的,你调用一个远程方法,就像调用本地函数一样。
| 类型 | 思维方式 | 适合场景 |
|---|---|---|
| HTTP/REST | 请求资源 | 公开 API、跨平台 |
| URPC | 调用方法 | 内部服务、高性能 |
URPC 是 HarmonyOS 提供的高性能远程过程调用。它不是简单的 HTTP 封装,是一套完整的 RPC 框架。
三、Client、Server 和远程方法
URPC 的基本结构很简单:Client 调用方,Server 提供方,中间是远程方法。
这段代码解决什么问题: 定义远程方法。
文件: rpc/UserService.ets
用途: 远程服务接口定义
接入位置: 客户端和服务端共用
import { rpc } from '@kit.RemoteCommunicationKit';
// 定义远程接口
export interface IUserService {
getUserInfo(userId: string): Promise<UserInfo>;
updateProfile(userId: string, profile: Profile): Promise<boolean>;
}
客户端拿到这个接口,调用的时候就像调用本地方法一样。但实际上,调用会被框架拦截,打包发到服务端。
四、一次调用的完整生命周期
完整的远程调用是这样的:
- 客户端调用
getUserInfo(userId); - 框架拦截调用,把方法名和参数序列化;
- 建立连接,发送请求包;
- 服务端收到请求,反序列化,找到对应方法;
- 服务端执行业务逻辑;
- 服务端把返回值序列化;
- 把响应包发回客户端;
- 客户端反序列化,拿到结果;
- 把结果返回给调用方。

五、弱网环境为什么容易出问题
URPC 特别强调弱网传输。为什么?因为手机网络不是一直稳定的。
| 网络情况 | 问题 |
|---|---|
| Wi-Fi 信号差 | 丢包、延迟高 |
| 蜂窝网络切换 | 连接中断、重连 |
| 多径传输 | Wi-Fi 和蜂窝同时传,选快的 |
多径传输是什么意思?就是 Wi-Fi 和蜂窝网络同时传同一份数据,哪条路快走哪条。这样即使 Wi-Fi 断了,蜂窝网络还在传,不会整个挂掉。
六、超时和异常传播为什么很重要
很多人写 RPC 只处理"成功"这一种情况。不对。
RPC 的失败情况太多了:
| 失败类型 | 说明 |
|---|---|
| 网络超时 | 服务器没响应 |
| 网络断开 | 连接断了 |
| 服务端错误 | 业务报错 |
| 序列化失败 | 参数打包出错 |
| 反序列化失败 | 结果解不开 |
每一种失败,客户端都要能处理。不能网络一断,整个应用就崩了。
七、几个容易踩的坑
第一个坑:把远程调用当成本地函数。它不是本地的,它有网络延迟,会失败。
第二个坑:循环里大量细粒度 RPC。循环调十次,十次网络往返,太慢了。应该批量传。
第三个坑:接口幂等性没有设计。网络重试了,服务器执行了两次,业务就乱了。
第四个坑:客户端超时但服务端仍继续执行。客户端不等了,服务端还在跑,资源浪费。
第五个坑:网络重试导致业务重复提交。点一次提交,网络不好重试,结果提交了两次。
第六个坑:把网络断开当普通函数异常。网络断开是常见情况,不是异常。
第七个坑:RPC 对象长期持有失效连接。连接断了还拿着用,每次都超时。

这次做远程调用最大的体会是:RPC 看起来像本地函数,但它本质是网络调用。你必须把它当网络问题来处理:超时、重试、幂等、异常。
每一个环节都有它存在的理由:序列化把参数打包、连接管理管网络、超时控制防卡死、异常处理防崩溃。
真正做的时候,最容易忽略的不是 API 怎么调,而是周边的工程问题:重试策略、幂等设计、连接生命周期、弱网处理。这些才是 RPC 真正难的地方。
更多推荐





所有评论(0)