|
| 1 | +import type { |
| 2 | + EventSubscription, |
| 3 | +} from 'react-native' |
| 4 | + |
| 5 | +import NativeModule from '../native-module' |
| 6 | + |
| 7 | +import { |
| 8 | + NO_ECHO_RTT, |
| 9 | +} from '../const/no-echo-rtt' |
| 10 | + |
| 11 | +import { |
| 12 | + PingStatus, |
| 13 | +} from '../PingStatus' |
| 14 | + |
| 15 | +import type { |
| 16 | + ICMPConstructorData, |
| 17 | + ICMPResult, |
| 18 | +} from './types' |
| 19 | + |
| 20 | +export class ICMP { |
| 21 | + |
| 22 | + private eventId: string = new Date().getTime().toString() + Math.random().toString() |
| 23 | + readonly host: string |
| 24 | + readonly count: number = 0 |
| 25 | + readonly packetSize: number = 56 |
| 26 | + readonly timeout: number = 1000 |
| 27 | + readonly ttl: number = 54 |
| 28 | + readonly interval: number = 1000 |
| 29 | + |
| 30 | + static NO_ECHO_RTT = NO_ECHO_RTT |
| 31 | + static NO_ECHO_TTL = -1 |
| 32 | + |
| 33 | + private pingEventSubscription: EventSubscription | null = null |
| 34 | + private pingEventHandler: ((result: ICMPResult) => void) | null = null |
| 35 | + |
| 36 | + constructor(data: ICMPConstructorData) { |
| 37 | + this.host = data.host |
| 38 | + this.count = data.count ?? this.count |
| 39 | + this.packetSize = data.packetSize ?? this.packetSize |
| 40 | + this.timeout = data.timeout ?? this.timeout |
| 41 | + this.ttl = data.ttl ?? this.ttl |
| 42 | + this.interval = data.interval ?? this.interval |
| 43 | + } |
| 44 | + |
| 45 | + ping( |
| 46 | + onPing: ( |
| 47 | + result: ICMPResult, |
| 48 | + ) => void, |
| 49 | + ) { |
| 50 | + if(!this.pingEventHandler) { |
| 51 | + NativeModule.icmp( |
| 52 | + this.eventId, |
| 53 | + this.host, |
| 54 | + this.count, |
| 55 | + this.packetSize, |
| 56 | + this.timeout, |
| 57 | + this.ttl, |
| 58 | + this.interval, |
| 59 | + ) |
| 60 | + |
| 61 | + this.pingEventHandler = onPing |
| 62 | + /* eslint-disable @typescript-eslint/no-unsafe-member-access */ |
| 63 | + this.pingEventSubscription = NativeModule.pingListener(( |
| 64 | + // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 65 | + result: any, |
| 66 | + ) => { |
| 67 | + this.pingEventHandler?.({ |
| 68 | + rtt: result.rtt, |
| 69 | + status: result.status, |
| 70 | + ttl: result.ttl, |
| 71 | + isEnded: result.isEnded, |
| 72 | + }) |
| 73 | + |
| 74 | + if(result.isEnded) { |
| 75 | + this.stop() |
| 76 | + } |
| 77 | + }) |
| 78 | + /* eslint-enable @typescript-eslint/no-unsafe-member-access */ |
| 79 | + } else { |
| 80 | + onPing({ |
| 81 | + rtt: NO_ECHO_RTT, |
| 82 | + ttl: ICMP.NO_ECHO_TTL, |
| 83 | + status: PingStatus.ECHOING, |
| 84 | + isEnded: true, |
| 85 | + }) |
| 86 | + } |
| 87 | + } |
| 88 | + |
| 89 | + stop() { |
| 90 | + if(this.pingEventHandler) { |
| 91 | + NativeModule.icmpRemove(this.eventId) |
| 92 | + this.pingEventSubscription?.remove() |
| 93 | + this.pingEventHandler = null |
| 94 | + } |
| 95 | + } |
| 96 | + |
| 97 | + isRunning() { |
| 98 | + return !!this.pingEventHandler |
| 99 | + } |
| 100 | + |
| 101 | +} |
0 commit comments