gongxiangp2/lib/network.ts
2025-10-26 09:11:04 +08:00

133 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 网络管理:智能检测并切换内外网
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)
}