|
@@ -4137,6 +4137,21 @@ const manualReconnect = () => {
|
|
|
createWebSocketConnection()
|
|
createWebSocketConnection()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 清理 WebSocket 连接(提取为独立函数)
|
|
|
|
|
+const cleanupWebSocketConnection = () => {
|
|
|
|
|
+ if (providerSocket.value) {
|
|
|
|
|
+ // 销毁连接
|
|
|
|
|
+ providerSocket.value.destroy()
|
|
|
|
|
+ providerSocket.value = null
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (docSocket.value) {
|
|
|
|
|
+ // 注意:doc 会被 provider.destroy() 自动销毁,不需要手动 destroy
|
|
|
|
|
+ // 但如果 provider 已经被销毁,这里置空即可
|
|
|
|
|
+ docSocket.value = null
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// 创建WebSocket连接
|
|
// 创建WebSocket连接
|
|
|
const createWebSocketConnection = async (type = 1) => {
|
|
const createWebSocketConnection = async (type = 1) => {
|
|
|
if (!api.yweb_socket || isConnecting.value) return
|
|
if (!api.yweb_socket || isConnecting.value) return
|
|
@@ -4150,6 +4165,7 @@ const createWebSocketConnection = async (type = 1) => {
|
|
|
// providerSocket.value.destroy()
|
|
// providerSocket.value.destroy()
|
|
|
// providerSocket.value = null
|
|
// providerSocket.value = null
|
|
|
// }
|
|
// }
|
|
|
|
|
+ cleanupWebSocketConnection()
|
|
|
|
|
|
|
|
// 清理之前的 token 更新定时器
|
|
// 清理之前的 token 更新定时器
|
|
|
if (authTokenUpdateTimer.value) {
|
|
if (authTokenUpdateTimer.value) {
|
|
@@ -4181,10 +4197,10 @@ const createWebSocketConnection = async (type = 1) => {
|
|
|
|
|
|
|
|
// 启动定期更新 token
|
|
// 启动定期更新 token
|
|
|
// 30分钟后再次更新
|
|
// 30分钟后再次更新
|
|
|
- // if (authTokenUpdateTimer.value) {
|
|
|
|
|
- // clearTimeout(authTokenUpdateTimer.value)
|
|
|
|
|
- // }
|
|
|
|
|
- // authTokenUpdateTimer.value = setTimeout(updateAuthToken, 30 * 60 * 1000) as unknown as NodeJS.Timeout
|
|
|
|
|
|
|
+ if (authTokenUpdateTimer.value) {
|
|
|
|
|
+ clearTimeout(authTokenUpdateTimer.value)
|
|
|
|
|
+ }
|
|
|
|
|
+ authTokenUpdateTimer.value = setTimeout(updateAuthToken, 30 * 60 * 1000) as unknown as NodeJS.Timeout
|
|
|
// authTokenUpdateTimer.value = setTimeout(updateAuthToken, 10 * 1000) as unknown as NodeJS.Timeout
|
|
// authTokenUpdateTimer.value = setTimeout(updateAuthToken, 10 * 1000) as unknown as NodeJS.Timeout
|
|
|
|
|
|
|
|
providerSocket.value.on('status', (event: any) => {
|
|
providerSocket.value.on('status', (event: any) => {
|
|
@@ -4206,94 +4222,126 @@ const createWebSocketConnection = async (type = 1) => {
|
|
|
messageInit()
|
|
messageInit()
|
|
|
// 连接成功后,读取当前计时器状态(Map)
|
|
// 连接成功后,读取当前计时器状态(Map)
|
|
|
if (docSocket.value) {
|
|
if (docSocket.value) {
|
|
|
- yTimerState.value = docSocket.value.getMap('timerState')
|
|
|
|
|
- const snapshot = yTimerState.value.toJSON()
|
|
|
|
|
- applyTimerStateSnapshot(snapshot)
|
|
|
|
|
- // 激光笔 map
|
|
|
|
|
- yLaserState.value = docSocket.value.getMap('laserState')
|
|
|
|
|
- const ls = yLaserState.value.toJSON()
|
|
|
|
|
- applyLaserStateSnapshot(ls)
|
|
|
|
|
- yLaserState.value.observe(() => {
|
|
|
|
|
- const s = yLaserState.value.toJSON()
|
|
|
|
|
- applyLaserStateSnapshot(s)
|
|
|
|
|
- })
|
|
|
|
|
- // 画图 map
|
|
|
|
|
- yWritingBoardState.value = docSocket.value.getMap('writingBoardState')
|
|
|
|
|
- const ws = yWritingBoardState.value.toJSON()
|
|
|
|
|
- console.log('📝 WebSocket连接成功,读取画图状态:', ws, '当前幻灯片:', currentSlide.value?.id)
|
|
|
|
|
- // 延迟应用,确保 currentSlide 已初始化
|
|
|
|
|
- nextTick(() => {
|
|
|
|
|
- // 如果 currentSlide 还没准备好,再等一帧
|
|
|
|
|
- if (currentSlide.value && currentSlide.value.id) {
|
|
|
|
|
- applyWritingBoardStateSnapshot(ws)
|
|
|
|
|
- }
|
|
|
|
|
- else {
|
|
|
|
|
- // 如果还没准备好,等待 currentSlide 变化(最多等待3秒)
|
|
|
|
|
- let timeoutId: any = null
|
|
|
|
|
- const unwatch = watch(() => currentSlide.value?.id, (slideId) => {
|
|
|
|
|
- if (slideId) {
|
|
|
|
|
- applyWritingBoardStateSnapshot(ws)
|
|
|
|
|
- unwatch()
|
|
|
|
|
- if (timeoutId) clearTimeout(timeoutId)
|
|
|
|
|
- }
|
|
|
|
|
- }, { immediate: true })
|
|
|
|
|
- // 3秒后如果还没准备好,强制应用一次
|
|
|
|
|
- timeoutId = setTimeout(() => {
|
|
|
|
|
- if (currentSlide.value && currentSlide.value.id) {
|
|
|
|
|
- applyWritingBoardStateSnapshot(ws)
|
|
|
|
|
- }
|
|
|
|
|
- unwatch()
|
|
|
|
|
- }, 3000)
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- yWritingBoardState.value.observe(() => {
|
|
|
|
|
- const s = yWritingBoardState.value.toJSON()
|
|
|
|
|
- if (currentSlide.value && currentSlide.value.id) {
|
|
|
|
|
- applyWritingBoardStateSnapshot(s)
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ initializeYjsData()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
else if (event.status === 'disconnected') {
|
|
else if (event.status === 'disconnected') {
|
|
|
- console.log('👉 WebSocket连接断开')
|
|
|
|
|
- connectionStatus.value = 'disconnected'
|
|
|
|
|
|
|
+ console.log('👉 连接断开,等待自动重连...')
|
|
|
isConnecting.value = false
|
|
isConnecting.value = false
|
|
|
- setTimeout(() => {
|
|
|
|
|
- createWebSocketConnection(2)
|
|
|
|
|
- }, 5000)
|
|
|
|
|
- }
|
|
|
|
|
- else if (event.status === 'closed') {
|
|
|
|
|
- console.log('👉 WebSocket连接断开closed')
|
|
|
|
|
- updateAuthToken().then(() => {
|
|
|
|
|
- providerSocket.value.connect() // 尝试重新连接
|
|
|
|
|
- })
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+ // else if (event.status === 'disconnected') {
|
|
|
|
|
+ // console.log('👉 WebSocket连接断开')
|
|
|
|
|
+ // connectionStatus.value = 'disconnected'
|
|
|
|
|
+ // isConnecting.value = false
|
|
|
|
|
+ // setTimeout(() => {
|
|
|
|
|
+ // createWebSocketConnection(2)
|
|
|
|
|
+ // }, 5000)
|
|
|
|
|
+ // }
|
|
|
|
|
+ // else if (event.status === 'closed') {
|
|
|
|
|
+ // console.log('👉 WebSocket连接断开closed')
|
|
|
|
|
+ // updateAuthToken().then(() => {
|
|
|
|
|
+ // providerSocket.value.connect() // 尝试重新连接
|
|
|
|
|
+ // })
|
|
|
|
|
+ // }
|
|
|
})
|
|
})
|
|
|
-
|
|
|
|
|
- // 监听连接错误
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // ✅ 只记录日志,不干预状态
|
|
|
providerSocket.value.on('connection-error', (error: any) => {
|
|
providerSocket.value.on('connection-error', (error: any) => {
|
|
|
- console.error('👉 WebSocket连接错误:', error)
|
|
|
|
|
- connectionStatus.value = 'disconnected'
|
|
|
|
|
- isConnecting.value = false
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- createWebSocketConnection(2)
|
|
|
|
|
- }, 5000)
|
|
|
|
|
|
|
+ console.error('👉 WebSocket 连接错误(将自动重连):', error)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+ providerSocket.value.on('connection-close', (event: any) => {
|
|
|
|
|
+ console.log('👉 WebSocket 连接关闭(将自动重连):', event)
|
|
|
|
|
+ })
|
|
|
|
|
+ // 监听连接错误
|
|
|
|
|
+ // providerSocket.value.on('connection-error', (error: any) => {
|
|
|
|
|
+ // console.error('👉 WebSocket连接错误:', error)
|
|
|
|
|
+ // connectionStatus.value = 'disconnected'
|
|
|
|
|
+ // isConnecting.value = false
|
|
|
|
|
+ // setTimeout(() => {
|
|
|
|
|
+ // createWebSocketConnection(2)
|
|
|
|
|
+ // }, 5000)
|
|
|
|
|
+ // })
|
|
|
|
|
+
|
|
|
|
|
+ // 监听连接关闭
|
|
|
|
|
+ // providerSocket.value.on('connection-close', (error: any) => {
|
|
|
|
|
+ // console.error('👉 WebSocket连接关闭:', error)
|
|
|
|
|
+ // connectionStatus.value = 'disconnected'
|
|
|
|
|
+ // isConnecting.value = false
|
|
|
|
|
+ // setTimeout(() => {
|
|
|
|
|
+ // updateAuthToken().then(() => {
|
|
|
|
|
+ // providerSocket.value.connect() // 尝试重新连接
|
|
|
|
|
+ // })
|
|
|
|
|
+ // }, 5000)
|
|
|
|
|
+ // })
|
|
|
}
|
|
}
|
|
|
catch (error) {
|
|
catch (error) {
|
|
|
console.error('👉 创建WebSocket连接失败:', error)
|
|
console.error('👉 创建WebSocket连接失败:', error)
|
|
|
connectionStatus.value = 'disconnected'
|
|
connectionStatus.value = 'disconnected'
|
|
|
isConnecting.value = false
|
|
isConnecting.value = false
|
|
|
- setTimeout(() => {
|
|
|
|
|
- createWebSocketConnection(2)
|
|
|
|
|
- }, 5000)
|
|
|
|
|
|
|
+ // setTimeout(() => {
|
|
|
|
|
+ // createWebSocketConnection(2)
|
|
|
|
|
+ // }, 5000)
|
|
|
|
|
+ cleanupWebSocketConnection()
|
|
|
|
|
+ setTimeout(createWebSocketConnection, 5000)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 启动 socket 连接检查定时器
|
|
// 启动 socket 连接检查定时器
|
|
|
// startSocketCheckTimer()
|
|
// startSocketCheckTimer()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// ✅ 提取业务初始化逻辑
|
|
|
|
|
+const initializeYjsData = () => {
|
|
|
|
|
+ if (!docSocket.value) return
|
|
|
|
|
+
|
|
|
|
|
+ yTimerState.value = docSocket.value.getMap('timerState')
|
|
|
|
|
+ const snapshot = yTimerState.value.toJSON()
|
|
|
|
|
+ applyTimerStateSnapshot(snapshot)
|
|
|
|
|
+ // 激光笔 map
|
|
|
|
|
+ yLaserState.value = docSocket.value.getMap('laserState')
|
|
|
|
|
+ const ls = yLaserState.value.toJSON()
|
|
|
|
|
+ applyLaserStateSnapshot(ls)
|
|
|
|
|
+ yLaserState.value.observe(() => {
|
|
|
|
|
+ const s = yLaserState.value.toJSON()
|
|
|
|
|
+ applyLaserStateSnapshot(s)
|
|
|
|
|
+ })
|
|
|
|
|
+ // 画图 map
|
|
|
|
|
+ yWritingBoardState.value = docSocket.value.getMap('writingBoardState')
|
|
|
|
|
+ const ws = yWritingBoardState.value.toJSON()
|
|
|
|
|
+ console.log('📝 WebSocket连接成功,读取画图状态:', ws, '当前幻灯片:', currentSlide.value?.id)
|
|
|
|
|
+ // 延迟应用,确保 currentSlide 已初始化
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ // 如果 currentSlide 还没准备好,再等一帧
|
|
|
|
|
+ if (currentSlide.value && currentSlide.value.id) {
|
|
|
|
|
+ applyWritingBoardStateSnapshot(ws)
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ // 如果还没准备好,等待 currentSlide 变化(最多等待3秒)
|
|
|
|
|
+ let timeoutId: any = null
|
|
|
|
|
+ const unwatch = watch(() => currentSlide.value?.id, (slideId) => {
|
|
|
|
|
+ if (slideId) {
|
|
|
|
|
+ applyWritingBoardStateSnapshot(ws)
|
|
|
|
|
+ unwatch()
|
|
|
|
|
+ if (timeoutId) clearTimeout(timeoutId)
|
|
|
|
|
+ }
|
|
|
|
|
+ }, { immediate: true })
|
|
|
|
|
+ // 3秒后如果还没准备好,强制应用一次
|
|
|
|
|
+ timeoutId = setTimeout(() => {
|
|
|
|
|
+ if (currentSlide.value && currentSlide.value.id) {
|
|
|
|
|
+ applyWritingBoardStateSnapshot(ws)
|
|
|
|
|
+ }
|
|
|
|
|
+ unwatch()
|
|
|
|
|
+ }, 3000)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ yWritingBoardState.value.observe(() => {
|
|
|
|
|
+ const s = yWritingBoardState.value.toJSON()
|
|
|
|
|
+ if (currentSlide.value && currentSlide.value.id) {
|
|
|
|
|
+ applyWritingBoardStateSnapshot(s)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// 处理连接断开
|
|
// 处理连接断开
|
|
|
const handleDisconnection = () => {
|
|
const handleDisconnection = () => {
|
|
|
if (reconnectAttempts.value < maxReconnectAttempts.value) {
|
|
if (reconnectAttempts.value < maxReconnectAttempts.value) {
|