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

# HarmonyOS 远场通信服务:在你的APP里用 C++ 发起 HTTP 请求

什么是远场通信服务

你写过网络请求代码吗?比如用 HTTP 从服务器获取数据。在鸿蒙开发中,用 ArkTS 发 HTTP 请求是很常见的。但有些场景需要更高的性能,比如游戏、音视频处理,这时候用 C++ 来发请求会更快。

远场通信服务(Remote Communication Kit)就是 HarmonyOS 提供的网络请求工具。它提供了 C 语言的 API,让你可以在 C++ 中发起 HTTP 请求。

你可能会问:ArkTS 不是有网络请求的接口吗?为什么还要用 C++?原因有几点:

  1. 性能:C++ 的执行速度比 ArkTS 快很多,特别是在处理大量数据时
  2. 复用:如果你已经有现成的 C++ 网络库,可以直接用,不用重写
  3. 底层控制:C++ 可以更精细地控制网络行为,比如超时、重试、断点续传等

简单说,远场通信服务就是让你用 C++ 来发 HTTP 请求,适合对性能要求高的场景。

核心功能

远场通信服务提供以下功能:

  1. 基础 URL 请求:发送 HTTP GET/POST 请求。这是最基本的功能,从服务器获取数据
  2. 超时控制:设置连接超时和传输超时。防止网络请求卡住,等太久用户体验差
  3. 断点续传:支持大文件断点续传。下载大文件时,如果网络断了,可以从断点继续下载,不用重新开始

环境搭建

硬件要求

  • 设备类型:华为手机
  • HarmonyOS 系统:HarmonyOS 5.0.0 Release 及以上

软件要求

  • DevEco Studio 版本:DevEco Studio 6.0.0 Release 及以上
  • HarmonyOS SDK 版本:HarmonyOS 6.0.0 Release SDK 及以上

搭建步骤

  1. 安装 DevEco Studio:去华为开发者官网下载安装
  2. 配置开发环境:确保网络环境正常
  3. 设备调试:使用真机进行调试

项目结构

├── entry/src/main │ ├── cpp │ │ ├── CMakeLists.txt // C 文件编译脚本 │ │ ├── napi_init.cpp // C 接口封装为 ArkTS │ │ └── types │ │ └── libentry │ │ ├── Index.d.ts // 导出封装的 ArkTS 接口 │ │ └── oh-package.json5 // ArkTS 与动态库映射 │ └── ets │ ├── entryability │ │ └── MainAbility.ets // UI Ability │ └── pages │ ├── BaseAddress.ets // 基础 URL 测试页面 │ ├── MainPage.ets // 主界面 │ ├── TimeOut.ets // 超时测试页面 │ └── TransferRange.ets // 断点续传页面

这个项目是 C++ 和 ArkTS 混合开发的:

  • cpp目录:C++ 代码,包括编译脚本、NAPI 封装
  • ets目录:ArkTS 代码,包括页面和业务逻辑

你可能会问:什么是 NAPI?NAPI 是 Node-API 的缩写,是鸿蒙系统提供的 C++ 和 ArkTS 之间的桥梁。通过 NAPI,ArkTS 可以调用 C++ 的函数。

C++ HTTP 请求流程

下面是使用 C++ 发起 HTTP 请求的完整流程:

配置 CMakeLists.txt

引入远场通信 SDK

创建请求对象

配置超时参数

创建会话对象

发送同步请求

请求是否成功?

获取响应数据

处理错误

释放资源

NAPI 封装流程

下面是 C++ 接口封装为 ArkTS 接口的流程:

编写 C++ 功能函数

定义 NAPI 函数

注册函数到模块

编译生成 .so 动态库

编写 Index.d.ts 声明文件

ArkTS 中 import 动态库

调用封装好的接口

NAPI 桥接调用 C++ 函数

返回结果给 ArkTS

第一步:配置编译脚本

CMakeLists.txt中配置远场通信 SDK:

# the minimum version of CMake. cmake_minimum_required(VERSION 3.4.1) project(RemoteCommunicationKitSdk) set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) if(DEFINED PACKAGE_FIND_FILE) include(${PACKAGE_FIND_FILE}) endif() include_directories(${NATIVERENDER_ROOT_PATH} ${NATIVERENDER_ROOT_PATH}/include) include_directories(${HMOS_SDK_NATIVE}/sysroot/usr/include) link_directories(${HMOS_SDK_NATIVE}/sysroot/usr/lib/aarch64-linux-ohos) add_library(entry SHARED napi_init.cpp) target_link_libraries(entry PUBLIC libace_napi.z.so librcp_c.so libhilog_ndk.z.so)

这里配置了:

  • 头文件路径:远场通信 SDK 的头文件。C++ 编译时需要知道去哪里找这些头文件
  • 链接库librcp_c.so是远场通信的核心库。你的 C++ 代码最终会链接到这个库
  • 编译目标entry是编译出来的动态库名字。ArkTS 通过这个名字来调用 C++ 代码

你可能会觉得这些配置很复杂。其实你不需要完全理解每一行,只要知道"这是告诉编译器去哪里找远场通信的库"就行了。

第二步:配置网络权限

module.json5中添加网络权限:

{"requestPermissions":[{"name":"ohos.permission.INTERNET"}]}

没有这个权限,网络请求会失败。这是鸿蒙系统的安全机制,应用必须声明需要网络权限,才能访问网络。

第三步:配置页面跳转

main_pages.json中配置页面路径:

{"src":["pages/MainPage","pages/BaseAddress","pages/TimeOut","pages/TransferRange"]}

配置好页面路径后,才能在不同页面之间跳转。这个文件告诉系统"我的应用有哪些页面"。

第四步:在 C++ 中发起 HTTP 请求

这是核心部分。在 C++ 中使用远场通信 SDK 发起请求。

引用头文件

#include"RemoteCommunicationKit/rcp.h"

引入远场通信 SDK 的头文件。rcp.h包含了所有的 API 函数声明。

配置请求参数

Rcp_Request*request=nullptr;Rcp_Configuration cfg{};cfg.transferConfiguration.timeout.connectMs=3000;// 连接超时 3 秒cfg.transferConfiguration.timeout.transferMs=10000;// 传输超时 10 秒if((request=HMS_Rcp_CreateRequest(url))==nullptr){gotoExit;}request->configuration=&cfg;

创建请求对象,配置超时时间:

  • connectMs:连接超时时间(毫秒)。3000 毫秒 = 3 秒,意思是如果 3 秒内连不上服务器,就放弃
  • transferMs:传输超时时间(毫秒)。10000 毫秒 = 10 秒,意思是如果 10 秒内数据没传输完,就放弃

为什么要设置超时?因为网络请求可能会卡住。比如服务器响应慢,或者网络不好。如果不设置超时,用户可能会一直等,体验很差。设置了超时,超时后会返回错误,你可以给用户一个提示。

创建会话并发送请求

Rcp_Session*session=nullptr;Rcp_Response*response=nullptr;if((session=HMS_Rcp_CreateSession(nullptr,&err))==nullptr){gotoExit;}response=HMS_Rcp_FetchSync(session,request,&err);if(err){gotoExit;}

创建会话对象,然后同步发送请求:

  1. HMS_Rcp_CreateSession:创建一个 HTTP 会话。会话就像一个"连接通道"
  2. HMS_Rcp_FetchSync:同步发送请求。这个函数会阻塞,直到请求完成或超时

HMS_Rcp_FetchSync是同步的,会阻塞当前线程。如果你在主线程调用,界面会卡住。所以在实际开发中,建议在子线程中调用。

第五步:用 NAPI 封装 C++ 接口

如果想在 ArkTS 中调用 C++ 接口,需要用 NAPI 封装。

EXTERN_C_STARTstaticnapi_valueInit(napi_env env,napi_value exports){napi_property_descriptor desc[]={{"Get",nullptr,Get,nullptr,nullptr,nullptr,napi_default,nullptr},{"GetWithTimeout",nullptr,GetWithTimeout,nullptr,nullptr,nullptr,napi_default,nullptr},{"GetWithTransferRange",nullptr,GetWithTransferRange,nullptr,nullptr,nullptr,napi_default,nullptr}};napi_define_properties(env,exports,sizeof(desc)/sizeof(desc[0]),desc);returnexports;}EXTERN_C_ENDstaticnapi_module demoModule={.nm_version=1,.nm_flags=0,.nm_filename=nullptr,.nm_register_func=Init,.nm_modname="entry",.nm_priv=((void*)0),.reserved={0},};extern"C"__attribute__((constructor))voidRegisterEntryModule(void){napi_module_register(&demoModule);}

把 C++ 接口封装成 ArkTS 可以调用的接口。这段代码做了以下事情:

  1. 定义了三个函数:GetGetWithTimeoutGetWithTransferRange
  2. 把这三个函数注册为 ArkTS 可以调用的接口
  3. 当 ArkTS 加载这个动态库时,会自动调用Init函数

你不需要完全理解这段代码,只要知道"这是把 C++ 函数暴露给 ArkTS"就行了。

第六步:导出 ArkTS 接口

Index.d.ts中导出接口:

exportconstGet:(url:string)=>string;exportconstGetWithTimeout:(url:string,connectTimeoutMs:number,transferTimeout:number)=>string;exportconstGetWithTransferRange:(url:string,from:number,to:number)=>string;

定义了三个接口:

  • Get:基础 URL 请求,只传一个 URL,返回响应内容
  • GetWithTimeout:带超时的请求,可以自定义连接超时和传输超时
  • GetWithTransferRange:断点续传请求,可以指定下载的范围

这个文件是 TypeScript 的类型声明文件,告诉 ArkTS “这些函数的参数和返回值是什么类型”。

第七步:在 ArkTS 中调用

importrcpSdkfrom'libentry.so';constkHttpServerAddress="https://httpbin.org/range/100";letres=rcpSdk.Get(kHttpServerAddress);console.info('rcp sdk Get result:',res);

导入 C++ 动态库,然后直接调用封装好的接口。libentry.so就是编译出来的动态库文件。

调用方式和普通 ArkTS 函数一样,完全感觉不到底层是 C++ 在执行。

三种请求模式

基础 URL 请求

privategetTokenSyn=async()=>{try{letres=rcpSdk.Get(kHttpServerAddress);this.content=`${kHttpServerAddress}传递成功`;console.info('rcp sdk Get result:',res);}catch(err){this.content=`${kHttpServerAddress}传递失败`+JSON.stringify(err);}}

最简单的请求,只传一个 URL。适合请求小数据量的场景,比如获取配置信息、获取用户信息等。

超时请求

privategetTimeoutSyn=async()=>{this.content='waiting for response';try{constresponse=rcpSdk.GetWithTimeout(kHttpServerAddress,this.connectMs,this.transferMs);console.info('timeout--success',JSON.stringify(response));this.content='timeout--success';}catch(err){console.error('timeout--err',JSON.stringify(err));this.content='timeout--err + '+JSON.stringify(err);}}

带超时控制的请求。如果在指定时间内没有完成,会抛出错误。适合对响应时间有要求的场景,比如实时数据查询。

断点续传

privategetTransferSyn=async()=>{try{constresp=rcpSdk.GetWithTransferRange(kHttpServerAddress,this.from,this.to);this.content=`${kHttpServerAddress}断点续传成功`;console.info('断点续传成功',resp);}catch(err){this.content=`${kHttpServerAddress}断点续传失败`+JSON.stringify(err);}}

断点续传请求,可以指定下载的范围。比如从第 100 字节开始下载,下载到第 200 字节。这在下载大文件时很有用,网络断了可以从断点继续下载。

实际应用场景

远场通信服务在实际开发中有很多用途:

游戏网络请求

// 游戏中用 C++ 发起网络请求,性能更好importrcpSdkfrom'libentry.so';asyncfunctionfetchGameData(apiUrl:string){letresponse=rcpSdk.Get(apiUrl);returnJSON.parse(response);}

游戏对性能要求很高,用 C++ 发起网络请求可以减少延迟。比如获取游戏配置、同步游戏状态等。

大文件下载

// 下载大文件,支持断点续传asyncfunctiondownloadFile(url:string,savePath:string){letfrom=0;letto=1024*1024;// 每次下载 1MBwhile(true){try{rcpSdk.GetWithTransferRange(url,from,to);from=to;to+=1024*1024;}catch(err){// 下载完成或出错break;}}}

下载大文件时,用断点续传可以提高可靠性。每次下载 1MB,下载完一块再下载下一块。如果网络断了,只需要重新下载当前这一块,不用从头开始。

高性能数据同步

// 用 C++ 处理大量数据同步asyncfunctionsyncData(dataUrl:string){letresponse=rcpSdk.GetWithTimeout(dataUrl,5000,30000);returnprocessResponse(response);}

数据同步场景需要高性能,用 C++ 可以更快地处理大量数据。

适用场景

远场通信服务适合以下场景:

  • 游戏应用:高性能网络请求
  • 音视频应用:流媒体数据传输
  • 文件传输:大文件下载、断点续传
  • 数据同步:大量数据的同步处理

注意事项

  1. 权限配置:需要配置 INTERNET 权限,否则网络请求会失败
  2. 编译配置:需要正确配置 CMakeLists.txt,否则编译会报错
  3. NAPI 封装:如果要在 ArkTS 中调用,需要 NAPI 封装,这个步骤不能省
  4. 错误处理:网络请求要处理各种错误情况,比如网络不通、服务器错误、超时等
  5. 超时设置:根据实际场景设置合理的超时时间,太短容易失败,太长用户体验差

总结

远场通信服务让你用 C++ 发起 HTTP 请求,核心流程:

  1. 配置编译脚本,引入远场通信 SDK
  2. 配置网络权限
  3. 在 C++ 中发起 HTTP 请求
  4. 用 NAPI 封装 C++ 接口
  5. 在 ArkTS 中调用封装好的接口

掌握了这些,你就能用 C++ 进行高性能的网络请求开发。

http://www.zskr.cn/news/1482779.html

相关文章:

  • 颠覆性数据主权工具:WeChatExporter如何智能解决微信聊天记录永久化难题
  • LOIC网络压力测试工具:从零开始的完整使用指南与安全实践
  • Solstice索致泰添加剂代理商是哪家 - 品牌排行榜
  • 实测12款论文降AIGC工具,效果最好的竟然是它! - 降AI小能手
  • Pro/E Wildfire 4.0/5.0可用的C++特征开发套件:含标准件库、模型命名、自定义特征等完整对话框工程
  • 机器狗自动跟随方案
  • [论文学习]LLM 遗忘机制对真实世界扰动资料的稳健性研究
  • 【太阳能】基于matlab模拟PEM电解模拟了24小时太阳能绿色氢电厂(每小时太阳能发电量、氢气产量、用水量、储罐动态以及每公斤H₂的成本
  • 当 AI 帮我写代码时,我学到了什么?
  • 如何实现企业级加密压缩包密码恢复:高效自动化解决方案指南
  • 风力涡轮机雷达信号仿真附matlab代码
  • MPC Video Renderer(MPC视频渲染器)
  • 书匠策AI官网www.shujiangce.com:揭秘一个让导师都查不出来的期刊论文“流水线“,附完整拆解
  • 系统常用运行库(CSRLPackage
  • 导师严选 2026 最新降AI率网站测评与推荐 - 降AI小能手
  • CLAUDE.md 是什么?它是所有 Skill 的总开关
  • MATLAB一键部署EMD/CeMD信号分解工具包(含多版本函数与可视化支持)
  • 3个关键步骤释放OneNote笔记潜能:onenote-md-exporter迁移实战指南
  • Oops Framework-8-由空项目创建第一个登录界面
  • 从光源到控制:2026年幻彩灯箱的技术迭代方向
  • CSDN AI数字营销订阅陷阱预警:自动续费暗门、阶梯计费盲区与紧急退订通道
  • 南京除甲醛公司口碑名单:绿居净环保等5家甲醛检测治理公司深度测评 - aZJ-111
  • Honey Select 2终极汉化补丁:3分钟实现游戏完全中文化
  • 英雄联盟Akari助手:免费开源游戏效率工具终极使用指南
  • 从零开始:如何用AICoverGen让AI为你喜欢的角色翻唱歌曲
  • 110、【Agent】【OpenCode】todowrite 工具提示词(示例)(四)
  • AI 辅助独立创作与创意工具产品化实践
  • 3大核心功能深度解析:RePKG如何破解Wallpaper Engine资源封装
  • 终极指南:三步解决Paradox游戏模组冲突,让你的游戏体验翻倍提升
  • 杭州甲醛检测治理除甲醛公司口碑名单:森氧家环保等5家深度测评 - aZJ-111