diff --git a/api/src/core/signaling.js b/api/src/core/signaling.js index c5a5ecd4..d4b616cc 100644 --- a/api/src/core/signaling.js +++ b/api/src/core/signaling.js @@ -69,9 +69,40 @@ export const setupSignalingServer = (httpServer) => { ws.on('error', (error) => { console.error('WebSocket错误:', error); - }); - - function handleCreateSession(ws, message) { + }); function handleCreateSession(ws, message) { + // 检查是否提供了现有会话ID(用于重连) + if (message.existingSessionId) { + const existingSession = sessions.get(message.existingSessionId); + if (existingSession && !existingSession.creator) { + // 重连到现有会话 + sessionId = message.existingSessionId; + userRole = 'creator'; + existingSession.creator = { ws, publicKey: message.publicKey }; + + ws.send(JSON.stringify({ + type: 'session_reconnected', + sessionId: sessionId + })); + + // 如果有在线的 joiner,通知双方重新建立连接 + if (existingSession.joiner && existingSession.joiner.ws.readyState === ws.OPEN) { + existingSession.joiner.ws.send(JSON.stringify({ + type: 'creator_reconnected', + publicKey: message.publicKey + })); + + ws.send(JSON.stringify({ + type: 'peer_already_joined', + publicKey: existingSession.joiner.publicKey + })); + } + + console.log(`创建者重连会话: ${sessionId}`); + return; + } + } + + // 创建新会话 sessionId = Math.random().toString(36).substring(2, 10); userRole = 'creator'; @@ -87,9 +118,7 @@ export const setupSignalingServer = (httpServer) => { })); console.log(`会话创建: ${sessionId}`); - } - - function handleJoinSession(ws, message) { + }function handleJoinSession(ws, message) { const session = sessions.get(message.sessionId); if (!session) { @@ -100,7 +129,8 @@ export const setupSignalingServer = (httpServer) => { return; } - if (session.joiner) { + // 检查是否已有活跃的 joiner + if (session.joiner && session.joiner.ws.readyState === ws.OPEN) { ws.send(JSON.stringify({ type: 'error', message: '会话已满' @@ -111,23 +141,31 @@ export const setupSignalingServer = (httpServer) => { sessionId = message.sessionId; userRole = 'joiner'; + // 设置或重新设置 joiner session.joiner = { ws, publicKey: message.publicKey }; - // 通知创建者有人加入,并交换公钥 + // 通知创建者有人加入(如果创建者在线) if (session.creator && session.creator.ws.readyState === ws.OPEN) { session.creator.ws.send(JSON.stringify({ type: 'peer_joined', publicKey: message.publicKey })); + + // 回复加入者创建者的公钥 + ws.send(JSON.stringify({ + type: 'session_joined', + publicKey: session.creator.publicKey + })); + + console.log(`用户重连到会话: ${sessionId}`); + } else { + // 创建者不在线,通知加入者等待 + ws.send(JSON.stringify({ + type: 'waiting_for_creator', + message: '等待创建者重新连接' + })); + console.log(`加入者在线,等待创建者: ${sessionId}`); } - - // 回复加入者创建者的公钥 - ws.send(JSON.stringify({ - type: 'session_joined', - publicKey: session.creator.publicKey - })); - - console.log(`用户加入会话: ${sessionId}`); } function handleSignaling(ws, message, sessionId, userRole) { @@ -153,15 +191,13 @@ export const setupSignalingServer = (httpServer) => { if (peer && peer.ws.readyState === ws.OPEN) { peer.ws.send(JSON.stringify(message)); } - } - - function handleDisconnect(sessionId, userRole) { + } function handleDisconnect(sessionId, userRole) { if (!sessionId) return; const session = sessions.get(sessionId); if (!session) return; - // 通知对端连接断开 + // 通知对端连接断开(但不删除会话) const peer = userRole === 'creator' ? session.joiner : session.creator; if (peer && peer.ws.readyState === ws.OPEN) { peer.ws.send(JSON.stringify({ @@ -169,9 +205,22 @@ export const setupSignalingServer = (httpServer) => { })); } - // 清理会话 - sessions.delete(sessionId); - console.log(`会话结束: ${sessionId}`); + // 只清理断开的用户,保留会话结构 + if (userRole === 'creator') { + console.log(`创建者断开连接: ${sessionId}`); + session.creator = null; + } else { + console.log(`加入者断开连接: ${sessionId}`); + session.joiner = null; + } + + // 如果双方都断开,才删除会话 + if (!session.creator && !session.joiner) { + sessions.delete(sessionId); + console.log(`会话结束(双方都断开): ${sessionId}`); + } else { + console.log(`会话保留,等待重连: ${sessionId}`); + } } }); diff --git a/web/src/routes/clipboard/+page.svelte b/web/src/routes/clipboard/+page.svelte index 9dfee6b5..06b9cb4f 100644 --- a/web/src/routes/clipboard/+page.svelte +++ b/web/src/routes/clipboard/+page.svelte @@ -1,4 +1,5 @@ -