feat(All) 修改结果展示样式,增加测试地区覆盖范围
This commit is contained in:
@@ -6,10 +6,17 @@ export interface IpInfoResponse {
|
||||
ip: string
|
||||
}
|
||||
|
||||
export interface LatencyTestResponse {
|
||||
nodeId: string
|
||||
latency: number | null
|
||||
success: boolean
|
||||
export interface BatchMeasurementResponse {
|
||||
measurementId: string
|
||||
}
|
||||
|
||||
export interface BatchResultResponse {
|
||||
status: 'in-progress' | 'finished'
|
||||
results: Array<{
|
||||
nodeId: string
|
||||
latency: number | null
|
||||
success: boolean
|
||||
}>
|
||||
}
|
||||
|
||||
export async function fetchUserIp(): Promise<string> {
|
||||
@@ -19,34 +26,67 @@ export async function fetchUserIp(): Promise<string> {
|
||||
return data.ip
|
||||
}
|
||||
|
||||
export async function testLatency(
|
||||
targetIp: string,
|
||||
nodeId: string
|
||||
): Promise<LatencyResult> {
|
||||
const res = await fetch(`${API_BASE}/latency`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ targetIp, nodeId }),
|
||||
})
|
||||
if (!res.ok) {
|
||||
return { nodeId, latency: null, status: 'failed' }
|
||||
}
|
||||
const data: LatencyTestResponse = await res.json()
|
||||
return {
|
||||
nodeId: data.nodeId,
|
||||
latency: data.latency,
|
||||
status: data.success ? 'success' : 'failed',
|
||||
}
|
||||
}
|
||||
|
||||
export async function testAllNodes(
|
||||
targetIp: string,
|
||||
target: string,
|
||||
onProgress: (result: LatencyResult) => void
|
||||
): Promise<void> {
|
||||
const promises = TEST_NODES.map(async (node) => {
|
||||
onProgress({ nodeId: node.id, latency: null, status: 'testing' })
|
||||
const result = await testLatency(targetIp, node.id)
|
||||
onProgress(result)
|
||||
for (const node of TEST_NODES) {
|
||||
onProgress({ nodeId: node.id, latency: null, status: 'pending' })
|
||||
}
|
||||
|
||||
const res = await fetch(`${API_BASE}/latency/batch`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ target }),
|
||||
})
|
||||
await Promise.all(promises)
|
||||
|
||||
if (!res.ok) {
|
||||
for (const node of TEST_NODES) {
|
||||
onProgress({ nodeId: node.id, latency: null, status: 'failed' })
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const { measurementId }: BatchMeasurementResponse = await res.json()
|
||||
|
||||
for (const node of TEST_NODES) {
|
||||
onProgress({ nodeId: node.id, latency: null, status: 'testing' })
|
||||
}
|
||||
|
||||
const startTime = Date.now()
|
||||
const timeout = 60000
|
||||
const completedNodes = new Set<string>()
|
||||
|
||||
while (Date.now() - startTime < timeout) {
|
||||
await new Promise(r => setTimeout(r, 800))
|
||||
|
||||
const pollRes = await fetch(`${API_BASE}/latency/batch/${measurementId}`)
|
||||
if (!pollRes.ok) continue
|
||||
|
||||
const data: BatchResultResponse = await pollRes.json()
|
||||
|
||||
for (const result of data.results) {
|
||||
if (result.success && !completedNodes.has(result.nodeId)) {
|
||||
completedNodes.add(result.nodeId)
|
||||
onProgress({
|
||||
nodeId: result.nodeId,
|
||||
latency: result.latency,
|
||||
status: 'success'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (data.status === 'finished') {
|
||||
for (const result of data.results) {
|
||||
if (!completedNodes.has(result.nodeId)) {
|
||||
onProgress({
|
||||
nodeId: result.nodeId,
|
||||
latency: result.latency,
|
||||
status: result.success ? 'success' : 'failed'
|
||||
})
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user