diff --git a/en/react-native-ping.md b/en/react-native-ping.md new file mode 100644 index 0000000000000000000000000000000000000000..021915ab6f05549de5e28716693d597ef188422f --- /dev/null +++ b/en/react-native-ping.md @@ -0,0 +1,576 @@ +> Template version: v0.4.0 + +

+

react-native-ping

+

+ +This project is based on [react-native-ping](https://github.com/RoJoHub/react-native-ping). + +This third-party library has been migrated to Gitcode and is now available for direct download from npm, the new package name is: `@react-native-ohos/react-native-ping`, The version correspondence details are as follows: + +| Name | Version | Release Information | Supported RN Version | Supported Autolink | Compile API Version | Community Baseline Version | npm Address | +| --------------| -------------- | ------------------------------ | ------------- | ------------- |------------------------ | ------------- | ------------- | +| @react-native-ohos/react-native-ping | ~ 1.3.0 | [Github Releases](https://github.com/react-native-oh-library/react-native-ping/releases) | 0.72.*/0.77.*/0.82.* | yes | API20+ | 1.2.8 | [Npm Address](https://www.npmjs.com/package/@react-native-ohos/react-native-ping) | + +## 1. Installation and Usage + +Go to the project directory and execute the following instruction: + + + +#### **npm** + +```bash +npm install @react-native-ohos/react-native-ping +``` + +#### **yarn** + +```bash +yarn add @react-native-ohos/react-native-ping +``` + + + +The following code shows the basic use scenario of the repository: + +> [!WARNING] The name of the imported repository remains unchanged. + +```js +// react-native-ping is used as an example. +import React, { useState, useEffect } from 'react'; +import { + View, + Text, + StyleSheet, + ScrollView, + TouchableOpacity, + ActivityIndicator, + Alert, +} from 'react-native'; +import Ping from '@react-native-ohos/react-native-ping'; + +const TestCase = ({ + title, + description, + onPress, + isLoading, + result, +}) => ( + + {title} + {description && {description}} + + {isLoading ? ( + + ) : ( + 开始测试 + )} + + {result !== null && {result}} + +); + +interface TrafficStats { + receivedNetworkSpeed: number; + sendNetworkSpeed: number; + receivedNetworkTotal: number; + sendNetworkTotal: number; +} + +interface TestResults { + [key: string]: string | null; +} + +interface LoadingTests { + [key: string]: boolean; +} + +const ReactNativePingDemo = () => { + const [loadingTests, setLoadingTests] = useState({}); + const [testResults, setTestResults] = useState({}); + const [trafficStats, setTrafficStats] = useState(null); + const [isLoadingTraffic, setIsLoadingTraffic] = useState(false); + + const runTest = async (testId: string, testFunction: () => Promise) => { + setLoadingTests(prev => ({ ...prev, [testId]: true })); + setTestResults(prev => ({ ...prev, [testId]: null })); + + try { + const result = await testFunction(); + setTestResults(prev => ({ + ...prev, + [testId]: `测试结果: ${result}`, + })); + } catch (error) { + const errorMessage = error.code + ? `测试失败 (${error.code}): ${error.message}` + : `测试失败: ${error.message || '未知错误'}`; + setTestResults(prev => ({ + ...prev, + [testId]: errorMessage, + })); + } finally { + setLoadingTests(prev => ({ ...prev, [testId]: false })); + } + }; + + const runAllTests = async () => { + const testIds = [ + 'testGoogleDNS', + 'test114DNS', + 'testInvalidHost', + 'testNoHost' + ]; + + for (const testId of testIds) { + if (!loadingTests[testId]) { + await runTest(testId, () => runSingleTest(testId)); + } + } + + Alert.alert('测试完成', '所有测试已执行完毕'); + }; + + const runSingleTest = async (testId) => { + switch (testId) { + case 'testGoogleDNS': + return testPing('8.8.8.8', 'Google DNS'); + case 'test114DNS': + return testPing('114.114.114.114', '114 DNS', { timeout: 5000 }); + case 'testInvalidHost': + return testPing('invalid-host.example.com', '无效主机', { timeout: 5000 }); + case 'testNoHost': + return testPing('', '未设置 host', { timeout: 5000 }); + default: + throw new Error('未知测试'); + } + }; + + const testPing = async (ipAddress: string, name: string, options: { timeout?: number } = {}) => { + try { + const start = Date.now(); + const rtt = await Ping.start(ipAddress, options); + console.log("chy rrt:", rtt) + return `${name} - RTT: ${rtt}ms`; + } catch (e) { + return JSON.stringify(e.message) + } + }; + + const loadTrafficStats = async () => { + setIsLoadingTraffic(true); + try { + const stats = await Ping.getTrafficStats(); + console.log("chy stats:", stats) + setTrafficStats(stats); + } catch (error) { + Alert.alert('获取流量统计失败', error.message); + } finally { + setIsLoadingTraffic(false); + } + }; + + useEffect(() => { + loadTrafficStats(); + }, []); + + return ( + + + react-native-ping 演示 + + 高性能 ICMP Ping 控制器 + + + + + 流量统计 + {isLoadingTraffic ? ( + + ) : trafficStats ? ( + + + 接收速度: {trafficStats.receivedNetworkSpeed} + + + 发送速度: {trafficStats.sendNetworkSpeed} + + + 接收总量: {trafficStats.receivedNetworkTotal} + + + 发送总量: {trafficStats.sendNetworkTotal} + + + ) : null} + + 刷新统计 + + + + + Ping 测试 + runTest('testGoogleDNS', () => runSingleTest('testGoogleDNS'))} + isLoading={loadingTests['testGoogleDNS']} + result={testResults['testGoogleDNS']} + /> + runTest('test114DNS', () => runSingleTest('test114DNS'))} + isLoading={loadingTests['test114DNS']} + result={testResults['test114DNS']} + /> + runTest('testInvalidHost', () => runSingleTest('testInvalidHost'))} + isLoading={loadingTests['testInvalidHost']} + result={testResults['testInvalidHost']} + /> + + runTest('testNoHost', () => runSingleTest('testNoHost'))} + isLoading={loadingTests['testNoHost']} + result={testResults['testNoHost']} + /> + + + + v) && styles.disabledButton]} + onPress={runAllTests} + disabled={Object.values(loadingTests).some(v => v)} + > + {Object.values(loadingTests).some(v => v) ? ( + + ) : ( + 运行所有测试 + )} + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#F5F5F5', + }, + header: { + backgroundColor: '#007AFF', + paddingVertical: 24, + paddingHorizontal: 16, + alignItems: 'center', + }, + title: { + fontSize: 24, + fontWeight: 'bold', + color: '#FFFFFF', + textAlign: 'center', + marginBottom: 8, + }, + subtitle: { + fontSize: 14, + color: 'rgba(255, 255, 255, 0.8)', + textAlign: 'center', + }, + sectionContainer: { + backgroundColor: '#FFFFFF', + marginVertical: 8, + paddingHorizontal: 16, + paddingVertical: 16, + }, + sectionTitle: { + fontSize: 18, + fontWeight: 'bold', + marginBottom: 16, + color: '#333333', + }, + testCaseContainer: { + backgroundColor: '#F8F8F8', + padding: 12, + borderRadius: 8, + marginBottom: 16, + }, + testCaseTitle: { + fontSize: 16, + fontWeight: '600', + marginBottom: 8, + color: '#333333', + }, + testCaseDescription: { + fontSize: 12, + color: '#666666', + marginBottom: 12, + lineHeight: 16, + }, + testButton: { + backgroundColor: '#007AFF', + paddingVertical: 8, + paddingHorizontal: 16, + borderRadius: 6, + alignItems: 'center', + }, + disabledButton: { + backgroundColor: '#CCCCCC', + }, + testButtonText: { + color: '#FFFFFF', + fontSize: 14, + fontWeight: '500', + }, + testResult: { + marginTop: 12, + fontSize: 14, + lineHeight: 20, + color: '#333333', + }, + statsContainer: { + backgroundColor: '#F8F8F8', + padding: 12, + borderRadius: 8, + marginBottom: 12, + }, + statItem: { + fontSize: 14, + color: '#333333', + marginBottom: 8, + }, + statValue: { + fontWeight: '600', + color: '#007AFF', + }, + refreshButton: { + backgroundColor: '#007AFF', + paddingVertical: 8, + paddingHorizontal: 16, + borderRadius: 6, + alignItems: 'center', + }, + refreshButtonText: { + color: '#FFFFFF', + fontSize: 14, + fontWeight: '500', + }, + runAllButton: { + backgroundColor: '#34C759', + paddingVertical: 12, + paddingHorizontal: 16, + borderRadius: 8, + alignItems: 'center', + justifyContent: 'center', + }, + runAllButtonText: { + color: '#FFFFFF', + fontSize: 16, + fontWeight: '600', + }, +}); + +export default ReactNativePingDemo; +``` + +## 2. Manual Link + +| | Supported Autolink | Supported RN Version | +|--------------------------------------|------------------|-----------| +| ~1.3.0 | Yes | 0.72/0.77/0.82 | + +Projects using AutoLink need to be configured according to this document, AutoLink framework guide.:https://gitcode.com/openharmony-sig/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md + +If the version you are using supports Autolink and the project has integrated Autolink, you can skip the ManualLink configuration. + +
+ ManualLink: This step provides guidance for manually configuring native dependencies. + +Open the `harmony` directory of the HarmonyOS project in DevEco Studio. + +### 2.1 Overrides RN SDK + +To ensure the project relies on the same version of the RN SDK, you need to add an `overrides` field in the project's root `oh-package.json5` file, specifying the RN SDK version to be used. The replacement version can be a specific version number, a semver range, or a locally available HAR package or source directory. + +For more information about the purpose of this field, please refer to the [official documentation](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-oh-package-json5-V5#en-us_topic_0000001792256137_overrides). + +```json +{ + "overrides": { + "@rnoh/react-native-openharmony": "^0.72.38" // ohpm version + // "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // a locally available HAR package + // "@rnoh/react-native-openharmony" : "./react_native_openharmony" // source code directory + } +} +``` + +### 2.2 Introducing Native Code + +Currently, two methods are available: + +- Use the HAR file. +- Directly link to the source code。 + +Method 1 (recommended): Use the HAR file. + +> [!TIP] The HAR file is stored in the `harmony` directory in the installation path of the third-party library. + +Open `entry/oh-package.json5` file and add the following dependencies: + +```json +"dependencies": { + "@react-native-ohos/react-native-ping": "file:../../node_modules/@react-native-ohos/react-native-ping/harmony/RNPing.har" + } +``` + +Click the `sync` button in the upper right corner. + +Alternatively, run the following instruction on the terminal: + +```bash +cd entry +ohpm install +``` + +Method 2: Directly link to the source code. + +> [!TIP] For details, see [Directly Linking Source Code](/en/link-source-code.md). + +### 2.3 Configuring CMakeLists and Introducing xxx Package + +Open `entry/src/main/cpp/CMakeLists.txt` and add the following code: + +```diff ++ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules") + +# RNOH_BEGIN: manual_package_linking_1 ++ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-ping/src/main/cpp" ./ping) +# RNOH_END: manual_package_linking_1 + +# RNOH_BEGIN: manual_package_linking_2 ++ target_link_libraries(rnoh_app PUBLIC rnoh_ping) +# RNOH_END: manual_package_linking_2 +``` + +Open `entry/src/main/cpp/PackageProvider.cpp` and add the following code: + +```diff +#include "RNOH/PackageProvider.h" +#include "generated/RNOHGeneratedPackage.h" ++ #include "RNCPingPackage.h" + +using namespace rnoh; + +std::vector> PackageProvider::getPackages(Package::Context ctx) { + return { + std::make_shared(ctx), ++ std::make_shared(ctx), + }; +} +``` + +### 2.4 Introducing react-native-ping Package to ArkTS + +Open the `entry/src/main/ets/RNPackagesFactory.ts` file and add the following code: + +```diff + ... ++ import {RNReactNativePingPackage} from '@react-native-ohos/react-native-ping/ts'; + +export function createRNPackages(ctx: RNPackageContext): RNPackage[] { + return [ ++ new RNReactNativePingPackage(ctx), + ]; +} +``` +
+ +### 2.5 Running + +Click the `sync` button in the upper right corner. + +Alternatively, run the following instruction on the terminal: + +```bash +cd entry +ohpm install +``` + +Then build and run the code. + +## 3. Constraints + +### 3.1 Compatibility + +Check the release version information in the release address of the third-party library: [\<@react-native-ohos/react-native-ping> Releases](https://github.com/react-native-oh-library/react-native-ping/releases) + +This document is verified based on the following versions: + +1. RNOH: 0.72.59/0.77.18-1/0.82.7; SDK: HarmonyOS-6.0.0(API20); IDE: DevEco Studio 6.0.1.260; ROM: NEXT.0.0.71. + +### 3.2 Permission Requirements + +(Enter the related permission configuration.) +open `entry/src/main/resources/base/element/string.json` and add: + +```diff +... +{ + "string": [ ++ { ++ "name": "ohos.permission.INTERNET", ++ }, + ] +} +``` + +### 3.3. API requirements + +> [!TIP] All versions of the current third-party libraries supporting compilation in `API20+` projects and execution on `API20+` ROMs. + +> [!TIP] The following features depend on specific API versions. Compiling the project with an API version lower than specified or running the ROM with an API version lower than specified may result in limited functionality. +1. Version 1.3.0 introduced [NetConn_ProbeResultInfo](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-netconnection-netconn-proberesultinfo) to define the detection result information returned in the `ping` function. `NetConn_ProbeResultInfo` needs to be compiled in a project that supports `API20+` and run on a ROM that supports `API20+`. Running it on lower versions will result in the ping function in the `start` method being unavailable. + +## 4. APIs + +> [!TIP] The **Platform** column indicates the platform where the properties are supported in the original third-party library. + +> [!TIP] If the value of **HarmonyOS Support** is **yes**, it means that the HarmonyOS platform supports this property; **no** means the opposite; **partially** means some capabilities of this property are supported. The usage method is the same on different platforms and the effect is the same as that of iOS or Android. + +### start +| Name | Description | Type | Required | Platform | HarmonyOS Support | +| ---- | ----------- | ---- | -------- | -------- | ------------------ | +| ipAddress | Ip | string | yes | ALL | yes | +| options | Timeout Configuration | object | no | ALL | no | + +### getTrafficStats +| Name | Description | Type | Required | Platform | HarmonyOS Support | +| ---- | ----------- | ---- | -------- | -------- | ------------------ | +| receivedNetworkSpeed | Download Speed per second | string | yes | ALL | yes | +| sendNetworkSpeed | Upload Speed per second | string | yes | ALL | yes | +| receivedNetworkTotal | Download Total | string | yes | ALL | yes | +| sendNetworkTotal | Upload Total | string | yes | ALL | yes | + +## 5. Known Issues + +- [ ] The options configuration for the start method is not taking effect +- [ ] The error code only supports PingUtil_Message_HostErrorNotSetHost and PingUtil_Message_HostErrorUnknown; others are not supported + +## 6. Others + +## 7. License + +This project is licensed under [MIT License (MIT)](). diff --git a/zh-cn/react-native-ping.md b/zh-cn/react-native-ping.md new file mode 100644 index 0000000000000000000000000000000000000000..2653bd2c104c4fe43b9ca693a6f9c31b1d9f2d1e --- /dev/null +++ b/zh-cn/react-native-ping.md @@ -0,0 +1,594 @@ +> 模板版本:v0.4.0 + +

+

react-native-ping

+

+ +本项目基于 [react-native-ping](https://github.com/RoJoHub/react-native-ping) 开发。 + +该第三方库支持直接从 npm 下载,包名为:`@react-native-ohos/react-native-ping` 版本所属关系如下: +| 三方库名称 | 三方库版本 | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | npm地址 | +| ------------ | ------------ | ------------------------------ | ------------- | ------------- |------------------------ | ------------- | ------------- | +| @react-native-ohos/react-native-ping | ~ 1.3.0 | [Github Releases](https://github.com/react-native-oh-library/react-native-ping/releases) | 0.72.*/0.77.*/0.82.* | 是 | API20+ | 1.2.8 | [Npm Address](https://www.npmjs.com/package/@react-native-ohos/react-native-ping) | + +## 1. 安装与使用 + +进入到工程目录并输入以下命令: + + + +#### **npm** + +```bash +npm install @react-native-ohos/react-native-ping +``` + +#### **yarn** + +```bash +yarn add @react-native-ohos/react-native-ping +``` + + + +下面的代码展示了这个库的基本使用场景: + +> [!WARNING] 使用时 import 的库名不变。 + +```js +/** + * react-native-ping 示例 + * 展示 React Native 中的 ICMP Ping 功能 + */ + +import React, { useState, useEffect } from 'react'; +import { + View, + Text, + StyleSheet, + ScrollView, + TouchableOpacity, + ActivityIndicator, + Alert, +} from 'react-native'; +import Ping from '@react-native-ohos/react-native-ping'; + +const TestCase = ({ + title, + description, + onPress, + isLoading, + result, +}) => ( + + {title} + {description && {description}} + + {isLoading ? ( + + ) : ( + 开始测试 + )} + + {result !== null && {result}} + +); + +interface TrafficStats { + receivedNetworkSpeed: number; + sendNetworkSpeed: number; + receivedNetworkTotal: number; + sendNetworkTotal: number; +} + +interface TestResults { + [key: string]: string | null; +} + +interface LoadingTests { + [key: string]: boolean; +} + +const ReactNativePingDemo = () => { + const [loadingTests, setLoadingTests] = useState({}); + const [testResults, setTestResults] = useState({}); + const [trafficStats, setTrafficStats] = useState(null); + const [isLoadingTraffic, setIsLoadingTraffic] = useState(false); + + const runTest = async (testId: string, testFunction: () => Promise) => { + setLoadingTests(prev => ({ ...prev, [testId]: true })); + setTestResults(prev => ({ ...prev, [testId]: null })); + + try { + const result = await testFunction(); + setTestResults(prev => ({ + ...prev, + [testId]: `测试结果: ${result}`, + })); + } catch (error) { + const errorMessage = error.code + ? `测试失败 (${error.code}): ${error.message}` + : `测试失败: ${error.message || '未知错误'}`; + setTestResults(prev => ({ + ...prev, + [testId]: errorMessage, + })); + } finally { + setLoadingTests(prev => ({ ...prev, [testId]: false })); + } + }; + + const runAllTests = async () => { + const testIds = [ + 'testGoogleDNS', + 'test114DNS', + 'testInvalidHost', + 'testNoHost' + ]; + + for (const testId of testIds) { + if (!loadingTests[testId]) { + await runTest(testId, () => runSingleTest(testId)); + } + } + + Alert.alert('测试完成', '所有测试已执行完毕'); + }; + + const runSingleTest = async (testId) => { + switch (testId) { + case 'testGoogleDNS': + return testPing('8.8.8.8', 'Google DNS'); + case 'test114DNS': + return testPing('114.114.114.114', '114 DNS', { timeout: 5000 }); + case 'testInvalidHost': + return testPing('invalid-host.example.com', '无效主机', { timeout: 5000 }); + case 'testNoHost': + return testPing('', '未设置 host', { timeout: 5000 }); + default: + throw new Error('未知测试'); + } + }; + + const testPing = async (ipAddress: string, name: string, options: { timeout?: number } = {}) => { + try { + const start = Date.now(); + const rtt = await Ping.start(ipAddress, options); + console.log("chy rrt:", rtt) + return `${name} - RTT: ${rtt}ms`; + } catch (e) { + return JSON.stringify(e.message) + } + }; + + const loadTrafficStats = async () => { + setIsLoadingTraffic(true); + try { + const stats = await Ping.getTrafficStats(); + console.log("chy stats:", stats) + setTrafficStats(stats); + } catch (error) { + Alert.alert('获取流量统计失败', error.message); + } finally { + setIsLoadingTraffic(false); + } + }; + + useEffect(() => { + loadTrafficStats(); + }, []); + + return ( + + + react-native-ping 演示 + + 高性能 ICMP Ping 控制器 + + + + + 流量统计 + {isLoadingTraffic ? ( + + ) : trafficStats ? ( + + + 接收速度: {trafficStats.receivedNetworkSpeed} + + + 发送速度: {trafficStats.sendNetworkSpeed} + + + 接收总量: {trafficStats.receivedNetworkTotal} + + + 发送总量: {trafficStats.sendNetworkTotal} + + + ) : null} + + 刷新统计 + + + + + Ping 测试 + runTest('testGoogleDNS', () => runSingleTest('testGoogleDNS'))} + isLoading={loadingTests['testGoogleDNS']} + result={testResults['testGoogleDNS']} + /> + runTest('test114DNS', () => runSingleTest('test114DNS'))} + isLoading={loadingTests['test114DNS']} + result={testResults['test114DNS']} + /> + runTest('testInvalidHost', () => runSingleTest('testInvalidHost'))} + isLoading={loadingTests['testInvalidHost']} + result={testResults['testInvalidHost']} + /> + + runTest('testNoHost', () => runSingleTest('testNoHost'))} + isLoading={loadingTests['testNoHost']} + result={testResults['testNoHost']} + /> + + + + v) && styles.disabledButton]} + onPress={runAllTests} + disabled={Object.values(loadingTests).some(v => v)} + > + {Object.values(loadingTests).some(v => v) ? ( + + ) : ( + 运行所有测试 + )} + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#F5F5F5', + }, + header: { + backgroundColor: '#007AFF', + paddingVertical: 24, + paddingHorizontal: 16, + alignItems: 'center', + }, + title: { + fontSize: 24, + fontWeight: 'bold', + color: '#FFFFFF', + textAlign: 'center', + marginBottom: 8, + }, + subtitle: { + fontSize: 14, + color: 'rgba(255, 255, 255, 0.8)', + textAlign: 'center', + }, + sectionContainer: { + backgroundColor: '#FFFFFF', + marginVertical: 8, + paddingHorizontal: 16, + paddingVertical: 16, + }, + sectionTitle: { + fontSize: 18, + fontWeight: 'bold', + marginBottom: 16, + color: '#333333', + }, + testCaseContainer: { + backgroundColor: '#F8F8F8', + padding: 12, + borderRadius: 8, + marginBottom: 16, + }, + testCaseTitle: { + fontSize: 16, + fontWeight: '600', + marginBottom: 8, + color: '#333333', + }, + testCaseDescription: { + fontSize: 12, + color: '#666666', + marginBottom: 12, + lineHeight: 16, + }, + testButton: { + backgroundColor: '#007AFF', + paddingVertical: 8, + paddingHorizontal: 16, + borderRadius: 6, + alignItems: 'center', + }, + disabledButton: { + backgroundColor: '#CCCCCC', + }, + testButtonText: { + color: '#FFFFFF', + fontSize: 14, + fontWeight: '500', + }, + testResult: { + marginTop: 12, + fontSize: 14, + lineHeight: 20, + color: '#333333', + }, + statsContainer: { + backgroundColor: '#F8F8F8', + padding: 12, + borderRadius: 8, + marginBottom: 12, + }, + statItem: { + fontSize: 14, + color: '#333333', + marginBottom: 8, + }, + statValue: { + fontWeight: '600', + color: '#007AFF', + }, + refreshButton: { + backgroundColor: '#007AFF', + paddingVertical: 8, + paddingHorizontal: 16, + borderRadius: 6, + alignItems: 'center', + }, + refreshButtonText: { + color: '#FFFFFF', + fontSize: 14, + fontWeight: '500', + }, + runAllButton: { + backgroundColor: '#34C759', + paddingVertical: 12, + paddingHorizontal: 16, + borderRadius: 8, + alignItems: 'center', + justifyContent: 'center', + }, + runAllButtonText: { + color: '#FFFFFF', + fontSize: 16, + fontWeight: '600', + }, +}); + +export default ReactNativePingDemo; +``` + +## 2. Link + +| | 是否支持autolink | RN框架版本 | +|--------------------------------------|------------------|-----------| +| ~1.3.0 | Yes | 0.72/0.77/0.82 | + +使用AutoLink的工程需要根据该文档配置,Autolink框架指导文档:https://gitcode.com/openharmony-sig/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md + +如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过ManualLink配置。 +
+ ManualLink: 此步骤为手动配置原生依赖项的指导 + +首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 `harmony`。 + +此步骤为手动配置原生依赖项的指导。 + +首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 `harmony`。 + +### 2.1. Overrides RN SDK + +为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 `oh-package.json5` 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。 + +关于该字段的作用请阅读[官方说明](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-oh-package-json5-V5#zh-cn_topic_0000001792256137_overrides) + +```json +{ + "overrides": { + "@rnoh/react-native-openharmony": "^0.72.38" // ohpm 在线版本 + // "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // 指向本地 har 包的路径 + // "@rnoh/react-native-openharmony" : "./react_native_openharmony" // 指向源码路径 + } +} +``` + +### 2.2. 引入原生端代码 + +目前有两种方法: + +- 通过 har 包引入; +- 直接链接源码。 + +方法一:通过 har 包引入(推荐) + +> [!TIP] har 包位于三方库安装路径的 `harmony` 文件夹下。 + +打开 `entry/oh-package.json5`,添加以下依赖 + +```json +"dependencies": { + "@react-native-ohos/react-native-ping": "file:../../node_modules/@react-native-ohos/react-native-ping/harmony/RNPing.har" + } +``` + +点击右上角的 `sync` 按钮 + +或者在命令行终端执行: + +```bash +cd entry +ohpm install +``` + +方法二:直接链接源码 + +> [!TIP] 如需使用直接链接源码,请参考[直接链接源码说明](/zh-cn/link-source-code.md) + +### 2.3. 配置 CMakeLists 和引入 RNCPingPackage + +打开 `entry/src/main/cpp/CMakeLists.txt`,添加: + +```diff ++ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules") + +# RNOH_BEGIN: manual_package_linking_1 ++ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-ping/src/main/cpp" ./ping) +# RNOH_END: manual_package_linking_1 + +# RNOH_BEGIN: manual_package_linking_2 ++ target_link_libraries(rnoh_app PUBLIC rnoh_ping) +# RNOH_END: manual_package_linking_2 +``` + +打开 `entry/src/main/cpp/PackageProvider.cpp`,添加: + +```diff +#include "RNOH/PackageProvider.h" +#include "generated/RNOHGeneratedPackage.h" ++ #include "RNCPingPackage.h" + +using namespace rnoh; + +std::vector> PackageProvider::getPackages(Package::Context ctx) { + return { + std::make_shared(ctx), ++ std::make_shared(ctx), + }; +} +``` + +### 2.5. 在 ArkTs 侧引入 react-native-ping Package + +打开 `entry/src/main/ets/RNPackagesFactory.ts`,添加: + +```diff + ... ++ import {RNReactNativePingPackage} from '@react-native-ohos/react-native-ping/ts'; + +export function createRNPackages(ctx: RNPackageContext): RNPackage[] { + return [ ++ new RNReactNativePingPackage(ctx), + ]; +} +``` +
+ +### 2.6. 运行 + +点击右上角的 `sync` 按钮 + +或者在命令行终端执行: + +```bash +cd entry +ohpm install +``` + +然后编译、运行即可。 + +## 3. 约束与限制 + +### 3.1. 兼容性 + +请到三方库相应的 Releases 发布地址查看 Release 配套的版本信息:[<@react-native-ohos/react-native-ping> Releases](https://github.com/react-native-oh-library/react-native-ping/releases) + +本文档内容基于以下版本验证通过: + +1. RNOH: 0.72.59/0.77.18-1/0.82.7; SDK: HarmonyOS-6.0.0(API20); IDE: DevEco Studio 6.0.1.260; ROM: NEXT.0.0.71。 + +### 3.2. 权限要求(如有) + +(填入相关权限配置) +打开 `entry/src/main/resources/base/element/string.json`,添加: + +```diff +... +{ + "string": [ ++ { ++ "name": "ohos.permission.INTERNET", ++ }, + ] +} +``` + +### 3.3. 编译运行API要求 + +> [!TIP] 当前三方库支持在 `API20+` 工程编译,及 `API20+` ROM运行。 + +> [!TIP] 以下功能依赖特定版本的API,使用 `低于指定API版本的工程编译` 或 `低于指定API版本的ROM运行` 均可能导致部分功能受限。 +1. 1.3.0版本引入[NetConn_ProbeResultInfo](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-netconnection-netconn-proberesultinfo),来定义ping功能中返回的探测结果信息,NetConn_ProbeResultInfo需要在支持`API20+`的工程编译,并在支持`API20+`的ROM上运行,低版本上运行将会导致start方法中的ping功能不可用。 + +## 6. API + +> [!TIP] "Platform"列表示该属性在原三方库上支持的平台。 + +> [!TIP] "HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。 + +### start +| Name | Description | Type | Required | Platform | HarmonyOS Support | +| ---- | ----------- | ---- | -------- | -------- | ------------------ | +| ipAddress | ping的Ip | string | yes | ALL | yes | +| options | 超时时间配置 | object | no | ALL | no | + +### getTrafficStats +| Name | Description | Type | Required | Platform | HarmonyOS Support | +| ---- | ----------- | ---- | -------- | -------- | ------------------ | +| receivedNetworkSpeed | 接收速度 | string | yes | ALL | yes | +| sendNetworkSpeed | 发送速度 | string | yes | ALL | yes | +| receivedNetworkTotal | 接收总量 | string | yes | ALL | yes | +| sendNetworkTotal | 发送总量 | string | yes | ALL | yes | + +## 7. 错误码 + +| Name | Description | Type | default | platform | HarmonyOS Support | +| :------- | :----------- | :------: | :---------: | -------- | ----------------- | +| PingUtil_Message_Timeout | 超时 | `string` | `0` | iOS,Android | NO | +| PingUtil_Message_PreviousPingIsStillRunning | 正在运行 | `string` | `1` | / | NO | +| PingUtil_Message_HostErrorNotSetHost | 未设置ip | `string` | `2` | iOS,Android | YES | +| PingUtil_Message_HostErrorUnknown | host未知错误 | `string` | `3` | iOS,Android | YES | +| PingUtil_Message_HostErrorHostNotFound | host错误、host找不到| `string` | `4` | Only iOS | NO | +| PingUtil_Message_Unknown | 未知错误 | `string` | `5` | Only iOS | NO | + +## 7. 遗留问题 + +- [ ] start方法的options配置不生效 +- [ ] 错误码只支持PingUtil_Message_HostErrorNotSetHost和PingUtil_Message_HostErrorUnknown,其他不支持 + +## 8. 其他 + + +## 9. 开源协议 + +本项目基于 [MIT License (MIT)]() ,请自由地享受和参与开源。