133 lines
3.5 KiB
TypeScript
133 lines
3.5 KiB
TypeScript
// 网络管理:智能检测并切换内外网
|
||
const INTERNAL_HOST = '192.168.58.20:4320'
|
||
|
||
function getExternalHost(): string {
|
||
if (typeof window === 'undefined') return ''
|
||
return window.location.host
|
||
}
|
||
|
||
export interface NetworkStatus {
|
||
isInternal: boolean
|
||
host: string
|
||
}
|
||
|
||
let currentNetwork: NetworkStatus | null = null
|
||
|
||
let isChecking = false
|
||
|
||
// 检测内网是否可达
|
||
async function checkInternalNetwork(): Promise<boolean> {
|
||
try {
|
||
const controller = new AbortController()
|
||
const timeoutId = setTimeout(() => controller.abort(), 2000) // 2秒超时
|
||
|
||
const response = await fetch(`http://${INTERNAL_HOST}/api/health`, {
|
||
method: 'HEAD',
|
||
signal: controller.signal,
|
||
mode: 'no-cors' // 避免CORS问题
|
||
})
|
||
|
||
clearTimeout(timeoutId)
|
||
return true // 如果请求没有抛出错误,说明内网可达
|
||
} catch (error) {
|
||
// 网络不可达或超时
|
||
return false
|
||
}
|
||
}
|
||
|
||
// 初始化网络检测
|
||
export async function initializeNetwork(): Promise<NetworkStatus> {
|
||
if (typeof window === 'undefined') {
|
||
return { isInternal: false, host: '' }
|
||
}
|
||
|
||
if (isChecking && currentNetwork) {
|
||
return currentNetwork
|
||
}
|
||
|
||
isChecking = true
|
||
const externalHost = getExternalHost()
|
||
|
||
try {
|
||
// 当前如果是访问内网地址,直接使用内网
|
||
if (window.location.hostname === '192.168.58.20') {
|
||
currentNetwork = {
|
||
isInternal: true,
|
||
host: INTERNAL_HOST
|
||
}
|
||
return currentNetwork
|
||
}
|
||
|
||
// 当前访问的是公网或localhost,尝试检测内网
|
||
const isInternalAvailable = await checkInternalNetwork()
|
||
|
||
if (isInternalAvailable) {
|
||
// 内网可达,切换到内网
|
||
currentNetwork = {
|
||
isInternal: true,
|
||
host: INTERNAL_HOST
|
||
}
|
||
console.log('✅ 内网可达,已切换到内网模式')
|
||
} else {
|
||
// 内网不可达,使用当前网络(公网)
|
||
currentNetwork = {
|
||
isInternal: false,
|
||
host: externalHost
|
||
}
|
||
console.log('⚠️ 内网不可达,使用公网模式')
|
||
}
|
||
} catch (error) {
|
||
console.error('网络检测失败:', error)
|
||
// 检测失败,使用当前网络
|
||
currentNetwork = {
|
||
isInternal: false,
|
||
host: externalHost
|
||
}
|
||
} finally {
|
||
isChecking = false
|
||
}
|
||
|
||
return currentNetwork
|
||
}
|
||
|
||
// 获取当前网络状态
|
||
export function getNetworkStatus(): NetworkStatus {
|
||
if (!currentNetwork) {
|
||
const externalHost = getExternalHost()
|
||
return { isInternal: false, host: externalHost }
|
||
}
|
||
return currentNetwork
|
||
}
|
||
|
||
// 获取API基础URL
|
||
export function getApiBaseUrl(): string {
|
||
if (!currentNetwork) {
|
||
return '' // 使用相对路径
|
||
}
|
||
return currentNetwork.isInternal ? `http://${currentNetwork.host}` : ''
|
||
}
|
||
|
||
// 定期检测网络(可选,用于自动重连)
|
||
export function startNetworkMonitoring(intervalMs: number = 30000) {
|
||
setInterval(async () => {
|
||
// 如果当前使用公网,定期尝试切换回内网
|
||
if (currentNetwork && !currentNetwork.isInternal) {
|
||
const isInternalAvailable = await checkInternalNetwork()
|
||
if (isInternalAvailable) {
|
||
currentNetwork = {
|
||
isInternal: true,
|
||
host: INTERNAL_HOST
|
||
}
|
||
console.log('🔄 已自动切换回内网模式')
|
||
// 触发页面刷新或状态更新
|
||
if (typeof window !== 'undefined') {
|
||
window.dispatchEvent(new CustomEvent('network-changed', {
|
||
detail: currentNetwork
|
||
}))
|
||
}
|
||
}
|
||
}
|
||
}, intervalMs)
|
||
}
|
||
|