Expose the Internet Control Message Protocol (ICMP) to React Native app natively.
Measure the round-trip time (RTT) by using ICMP echo request packets to the intended destination and iterate it in native side.
🚀 This library is supported in New Architecture (Turbo Modules)
- Platforms
- Requirements
- Installation
- APIs
- Definitions
- Migrating V1 to V2
- Android Emulator Limitations
| Platform | Compatible | Remarks |
|---|---|---|
| Android | ✅ | |
| iOS | ✅ | |
| Windows | ❌ | |
| macOS | ✅ | |
| Web | ❌ | There is no ICMP in the web |
This library requires explicit library and React Native version due to Turbo Modules capabilities and backward compatibility support
This library requires React Native >= 0.76 version. If you are using the latest React Native, you're good to go. Otherwise, either you need to upgrade your React Native version or you can opt-out the new architecture of your app and see the Old Architecture.
This library marked for React Native >= 0.76 as the peerDependencies, but actually you can use this library if you're in React Native >= 0.72 version. You need to override this library's peer dependency by adding overrides property of your package.json
{
"name": "yourapp",
"private": true
"dependencies": {
"ping-react-native": "libraryVersion"
},
"overrides": {
"ping-react-native": {
"react-native": ">=0.72"
}
}
}Cannot guarantee for older React Native versions support. It requires some tests.
npm
npm install ping-react-native
or with Yarn
yarn add ping-react-native
A bare JavaScript class to use ICMP controller of native module
import { useRef } from 'react'
import { Button } from 'react-native'
import {
ICMP,
type ICMPResult,
} from 'ping-react-native'
export default function App(): React.JSX.Element {
const
icmp =
useRef<ICMP | null>(
new ICMP({ host: '1.1.1.1', packetSize: 64, timeout: 1000, count: 3 })
),
[result, setResult] =
useState<ICMPResult | null>(null)
useEffect(() => {
const icmpRef = icmp.current
return () => {
icmpRef?.stop()
}
}, [])
const onPress = async () => {
icmp.current?.stop() // Stop previous runner if any
icmp.current?.ping(res => {
setResult({
rtt: result.rtt,
ttl: result.ttl,
status: result.status,
isEnded: result.isEnded,
})
})
}
return (
<Button
title="Ping"
onPress={ onPress }
/>
)
}- Constructors: (data: ICMPConstructorData)
| Data Properties | Type | Required | Default Value | Remarks |
|---|---|---|---|---|
| host | string |
Yes | valid host, e.g. 1.1.1.1 or guthib.com. Invalid host or unknown service will return ping result with ICMPStatus.UNKNOWN_HOST status |
|
| packetSize | number | null | undefined |
No | 56 | in bytes |
| timeout | number | null | undefined |
No | 1000 | in milliseconds |
| ttl | number | null | undefined |
No | 54 | time-to-live |
| count | number | null | undefined |
No | 0 | amount of try to ping. 0 is infinite count. Remember to stop the ping before unmounting your component |
| interval | number | null | undefined |
No | 1000 | in milliseconds |
| Method | Return | Remarks |
|---|---|---|
| ping | void |
Run the ICMP ping with arguments that has been defined from constructor. This method is an event listener that will invoke your callback function. If the method is invoked again while the previous process is still running, it will invoke your callback with ICMPStatus.ECHOING status. |
| stop | void |
Stop current ICMP ping request. It's important to invoke this function to cleanup ICMP request to avoid memory leaks. It's safe to invoke this method even if there is no ping requests are running. |
| Property | Type |
|---|---|
| host | readonly string |
| packetSize | readonly number |
| timeout | readonly number |
| ttl | readonly number |
| count | readonly number |
| interval | readonly number |
| Static Member | Type | Value | Remarks |
|---|---|---|---|
| NO_ECHO_RTT | number |
-1 | Just an constant whenever the status of ping result is not ICMPStatus.ECHO. It is used in the rtt result. |
| NO_ECHO_TTL | number |
-1 | Just an constant whenever the status of ping result is not ICMPStatus.ECHO. It is used in the ttl result. |
| Status | enum |
ICMPStatus |
See ICMPStatus. |
IT'S NOT SAFE to unmount your component without invoke the stop method if there are ICMP requests that still running. Your app may still has ICMP requests that still running in the background. Consider to use useICMP hook that do the cleanup automatically.
Do not iterate the ping method like with setInterval unless you really need it. The count argument is the iteration that has been done in native side.
A React hook of encapsulated ICMP class that you may use it to simplify the cleanup handling
import {
useICMP,
} from 'ping-react-native'
export default function App(): React.JSX.Element {
const { isRunning, result } = useICMP({
host: 'guthib.com',
packetSize: 64,
timeout: 1000,
interval: 1000,
count: 10,
// enabled: false // It's enabled by default. You can control when the ICMP should run
})
useEffect(() => {
if(result) {
console.log('Result: ', result.rtt, result.ttl, result.status)
}
}, [result])
}You can see full example at /example/src/screens/ping-runner/index.tsx
It's safe to unmount your component if the subsequent ICMP request is still running. This hook will do the cleanup automatically.
- Returns: UseICMP
| Properties | Type | Remarks |
|---|---|---|
| isRunning | boolean |
|
| result | object |
See ICMPResult |
(host: string) => Promise<string | null>
Gets the host name from an IP address.
If the host argument was given with a host name, a reverse name lookup still will be performed and the result will be returned based on the system configured name lookup service.
The Promise will never be rejected. It will return null if it fails.
(host: string) => Promise<string | null>
Gets the host address from a host name. Returns the IP address string in textual presentation.
The Promise will never be rejected. It will return null if it fails.
| Properties | Type | Remarks |
|---|---|---|
rtt |
number |
When the status is not ICMPStatus.ECHO, the value will be -1 (NO_ECHO_RTT) |
ttl |
number |
When the status is not ICMPStatus.ECHO, the value will be -1 (NO_ECHO_TTL) |
status |
enum |
See ICMPStatus. |
isEnded |
boolean |
true if there is no subsequent ping requests. |
| Properties | Type | Remarks |
|---|---|---|
host |
string |
Can either be a machine name, such as "guthib.com", or a textual representation of its IP address. |
packetSize |
number | null | undefined |
Value in bytes. If it smaller than zero, the promise result will be returned with ICMPStatus.INVALID_ARG status. |
ttl |
number | null | undefined |
time-to-live |
timeout |
number | null | undefined |
Value in milliseconds. |
count |
number | null | undefined |
Amount of try to ping. 0 is infinite count |
interval |
number | null | undefined |
Value in milliseconds. |
| Properties | Type | Remarks |
|---|---|---|
isRunning |
boolean |
A React state. false if there is no subsequent ping requests |
result |
object | undefined |
See ICMPResult |
It extends ICMPConstructorData.
| Member | Value | Remarks |
|---|---|---|
ECHO |
2 |
Success |
ECHOING |
1 |
When the ping method is invoked when the previous process still running |
TIMEDOUT |
0 |
|
INVALID_ARG |
-1 |
Invalid argument. such as illegal packet size, ttl out of range. |
UNKNOWN_HOST |
-2 |
|
UNKNOWN_FAILURE |
-3 |
There is breaking change 2.x version. See migration guide.
Depending on the environment, the emulator might not be able to support ICMP. See Local networking limitations.
Instead, you can use Android physical device and run React Native app in it.