diff --git a/src/utils/talkSocket.ts b/src/utils/talkSocket.ts index d76fecd..e42c720 100644 --- a/src/utils/talkSocket.ts +++ b/src/utils/talkSocket.ts @@ -45,6 +45,8 @@ let CurrentToken = '' let HeartbeatTimer: ReturnType | null = null /** 是否已针对 401 重连过一次(防止无限刷新令牌) */ let ReauthAttempted = false +/** 本次连接周期是否已提示过连接失败(重连期间不重复弹提示) */ +let ConnectErrorReported = false /** 连接中 Promise(并发调用去重) */ let Connecting: Promise | null = null @@ -112,6 +114,7 @@ async function HandleUnauthorized(): Promise { function BindCoreEvents(socket: Socket): void { socket.on('connect', () => { ReauthAttempted = false + ConnectErrorReported = false // 命名空间鉴权:auth.Token 已携带,仍按契约显式发一次 talk:auth socket.emit('talk:auth', { Token: CurrentToken }) StartHeartbeat(socket) @@ -119,6 +122,15 @@ function BindCoreEvents(socket: Socket): void { socket.on('disconnect', () => { StopHeartbeat() }) + // 连接建立失败(如 CORS 被拒、网络不可达):把原因透给页面,避免"什么都看不到" + socket.on('connect_error', (error: Error) => { + if (ConnectErrorReported) return + ConnectErrorReported = true + Dispatch('talk:error', { + code: 0, + msg: `Talk 实时通道连接失败:${error?.message || '未知原因'}(消息将不会实时到达)`, + }) + }) // 重连前刷新 auth,保证使用最新令牌 socket.io.on('reconnect_attempt', () => { socket.auth = { Token: CurrentToken } @@ -203,6 +215,7 @@ export function disconnectTalkSocket(): void { SocketInstance = null } ReauthAttempted = false + ConnectErrorReported = false CurrentToken = '' Connecting = null }