autobots-lib
Version:
汽车人基础库
173 lines (148 loc) • 4.41 kB
JavaScript
import {
Alert,
Platform,
NativeModules,
NativeAppEventEmitter
} from 'react-native';
import Jump from './jump';
function timeoutPromise(ms, promise) {
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
reject(new Error('promise timeout'));
}, ms);
promise.then(
res => {
clearTimeout(timeoutId);
resolve(res);
},
err => {
clearTimeout(timeoutId);
reject(err);
}
);
});
}
class _InternalNetworkMonitor {
constructor() {
this.map = {};
}
// 连接 vpn
_connectVpn(handler) {
const subscription = NativeAppEventEmitter.addListener(
'event_custom_message_back',
evt => {
let data = null;
if (Platform.OS === 'android') {
data = JSON.parse(evt.result);
} else {
data = JSON.parse(evt);
}
if (data && data.where === 'vpn') {
handler && handler(true);
} else {
handler && handler(false);
}
}
);
this.map[handler].push(subscription);
Jump.InitOpen('vpn', 0, 'apps/rn/api/bundle/vpn', 3, {
outConnect: 'direct'
});
}
// 首次获取 vpn 连接状态回调
_handleVpnStatusCallback(evt, handler) {
let isConnected = false;
if (Platform.OS === 'ios') {
isConnected = evt.data === 3;
} else {
isConnected = evt.data;
}
if (isConnected) {
// 已经连接
handler && handler(true);
} else {
Alert.alert('VPN未连接,暂时无法访问,是否现在连接VPN?', '', [
{text: '连接', onPress: () => this._connectVpn(handler)},
{text: '不连接', onPress: () => handler && handler(false)}
]);
}
}
connectVpn = async (handler) => {
let result = await NativeModules.VpnModule.connectVpn();
if (result) {
handler(true)
}
}
// 添加是否内网监听
addListener(handler) {
// 防止重复添加同一个回调
if (this.map[handler]) return;
this.map[handler] = [];
if (NativeModules.VpnModule) {
this.connectVpn(handler)
} else {
// 判断是否处于内网
const checkUrl = 'https://app.corpautohome.com/newautobots/checkIntranet';
const fetchPromise = fetch(checkUrl, {method: 'POST'});
timeoutPromise(15000, fetchPromise)
.then(response => response.json())
.then(json => {
if (json && json.code === 200) {
handler && handler(true);
} else {
// 如果不处于内网获取当前 vpn 连接状态
const url = 'autobots://rn/getVpnStatus';
if (Platform.OS === 'ios') {
// iOS 需要手动调用方法,然后状态会通过 event_vpnstate_back 传过来
const subscription = NativeAppEventEmitter.addListener(
'event_vpnstate_back',
evt => this._handleVpnStatusCallback(evt, handler)
);
this.map[handler].push(subscription);
NativeModules.AppLoader.callNative(url, () => {
});
} else {
// Android 会直接返回过来
// 但该 api 只存在于 3.4.5 版本以上,以下的版本调用直接返回 false
if (NativeModules.RNModule.isVpnConnected) {
NativeModules.RNModule.isVpnConnected(res => {
this._handleVpnStatusCallback({data: res}, handler);
});
} else {
handler && handler(false);
}
}
}
})
.catch(error => handler && handler(false));
}
}
// 移除监听
removeListener(handler) {
for (let subscription of this.map[handler]) {
subscription && subscription.remove();
}
this.map[handler] = null;
}
// 移除所有监听
removeAllListeners() {
for (let value of Object.values(this.map)) {
for (let subscription of value) {
subscription && subscription.remove();
}
}
this.map = {};
}
}
const monitor = new _InternalNetworkMonitor();
export default class InternalNetworkMonitor {
static addListener(handler) {
monitor.addListener(handler);
}
static removeListener(handler) {
monitor.removeListener(handler);
}
static removeAllListeners() {
monitor.removeAllListeners();
}
}