将http轮询改为 长轮询请求挂起
This commit is contained in:
@@ -2,7 +2,7 @@ import type { Files } from 'monaco-tree-editor'
|
||||
|
||||
let roomId: string | null = null
|
||||
let serverUrl: string | null = null
|
||||
let pollIntervalMs = 1000
|
||||
let pollIntervalMs = 100
|
||||
let isPolling = false
|
||||
let pollingTimeout: number | null = null
|
||||
|
||||
@@ -32,29 +32,6 @@ function getParamsFromUrl(): { roomId: string | null } {
|
||||
return { roomId }
|
||||
}
|
||||
|
||||
async function httpPost(path: string, data: any): Promise<any> {
|
||||
const url = `${serverUrl}${path}`
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP错误: ${response.status} ${response.statusText}`)
|
||||
}
|
||||
|
||||
return await response.json()
|
||||
} catch (error) {
|
||||
console.error('HTTP请求失败:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export async function initWebSocketConnection(): Promise<void> {
|
||||
const params = getParamsFromUrl()
|
||||
roomId = params.roomId
|
||||
@@ -67,6 +44,17 @@ export async function initWebSocketConnection(): Promise<void> {
|
||||
console.log('HTTP连接已初始化,服务器:', serverUrl)
|
||||
console.log('房间ID:', roomId)
|
||||
|
||||
// 处理挂起的初始请求
|
||||
for (const request of pendingInitialRequests) {
|
||||
try {
|
||||
const result = await sendFileOperationInternal(request.operation, request.data)
|
||||
request.resolve(result)
|
||||
} catch (error) {
|
||||
request.reject(error as Error)
|
||||
}
|
||||
}
|
||||
pendingInitialRequests.length = 0
|
||||
|
||||
startPolling()
|
||||
return Promise.resolve()
|
||||
}
|
||||
@@ -86,18 +74,33 @@ function stopPolling() {
|
||||
}
|
||||
|
||||
async function pollForResponses() {
|
||||
if (!isPolling || !roomId) return
|
||||
if (!isPolling || !roomId || !serverUrl) return
|
||||
|
||||
try {
|
||||
const response = await httpPost('/api/frontend/receive', {
|
||||
room_id: roomId,
|
||||
const response = await fetch(`${serverUrl}/api/frontend/receive`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
room_id: roomId,
|
||||
}),
|
||||
})
|
||||
|
||||
if (response.success && response.message) {
|
||||
handleMessage(response.message)
|
||||
if (response.ok) {
|
||||
const data = await response.json()
|
||||
if (data.success && data.message) {
|
||||
handleMessage(data.message)
|
||||
}
|
||||
} else {
|
||||
console.error('轮询请求失败:', response.status)
|
||||
// 短暂的延迟后重试
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('轮询消息失败:', error)
|
||||
// 网络错误,稍后重试
|
||||
await new Promise((resolve) => setTimeout(resolve, 5000))
|
||||
}
|
||||
|
||||
if (isPolling) {
|
||||
@@ -130,8 +133,13 @@ function handleFileOperationResponse(data: any): void {
|
||||
}
|
||||
}
|
||||
|
||||
function sendFileOperationInternal(operationType: string, data?: any, timeoutMs: number = 30000): Promise<any> {
|
||||
async function sendFileOperationInternal(operationType: string, data?: any, timeoutMs: number = 30000): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!serverUrl || !roomId) {
|
||||
reject(new Error('未初始化连接'))
|
||||
return
|
||||
}
|
||||
|
||||
const requestId = generateRequestId()
|
||||
|
||||
const timeout = window.setTimeout(() => {
|
||||
@@ -143,21 +151,28 @@ function sendFileOperationInternal(operationType: string, data?: any, timeoutMs:
|
||||
|
||||
pendingRequests.set(requestId, { resolve, reject, timeout })
|
||||
|
||||
httpPost('/api/frontend/send', {
|
||||
room_id: roomId,
|
||||
message: {
|
||||
type: 'file_operation',
|
||||
requestId: requestId,
|
||||
operation_type: operationType,
|
||||
data: data,
|
||||
room_id: roomId,
|
||||
fetch(`${serverUrl}/api/frontend/send`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
room_id: roomId,
|
||||
message: {
|
||||
type: 'file_operation',
|
||||
requestId: requestId,
|
||||
operation_type: operationType,
|
||||
data: data,
|
||||
room_id: roomId,
|
||||
},
|
||||
}),
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.success) {
|
||||
.then(async (response) => {
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text()
|
||||
pendingRequests.delete(requestId)
|
||||
clearTimeout(timeout)
|
||||
reject(new Error(response.message || '发送请求失败'))
|
||||
reject(new Error(errorText || `发送请求失败: ${response.status}`))
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
||||
Reference in New Issue
Block a user