diff --git a/DESIGN.md b/DESIGN.md index a19427e..092d05a 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -189,7 +189,7 @@ WebSocket 挂载在 HTTP Server 上,客户端连接地址的形式为 `ws:// { - try { - const data = JSON.parse(message.toString()); - console.log("收到WebSocket消息:", data); + try { + const data = JSON.parse(message.toString()); + console.log("收到WebSocket消息:", data); - handleMessage(username, data); - } catch (error) { - console.error("WebSocket消息处理失败:", error); - } - }); + // websocket收到消息,必须通过解析data内容才知道谁是发送者谁是接收者 + handleMessage(data, ws); + } catch (error) { + console.error("WebSocket消息处理失败:", error); + } + }); // 连接关闭 ws.on("close", () => { removeConnection(username); - + // 通知所有在线用户当前在线用户列表 broadcast({ type: "userOnline", @@ -87,13 +89,13 @@ function initWebSocket(server) { } // 处理WebSocket消息 -function handleMessage(username, data) { +function handleMessage(data, ws) { switch (data.type) { case "sendMessage": - handleSendMessage(username, data); + handleSendMessage(data, ws); break; case "ack": - handleAck(data); + handleAck(data, ws); break; default: @@ -102,21 +104,36 @@ function handleMessage(username, data) { } // 处理发送消息 -function handleSendMessage(senderName, data) { +function handleSendMessage(data, ws) { + const senderName = ws.username; const messageId = data.messageId; const receiverName = data.receiverName; const content = data.content; + if (!messageId) { + console.log("消息缺少 messageId"); + return; + } + + if (!receiverName) { + console.log("消息缺少接收者"); + return; + } + + if (!content) { + console.log("消息内容为空"); + return; + } + console.log( `${senderName} → ${receiverName}:${content}` ); const sql = ` - INSERT INTO messages - (message_id, sender_name, receiver_name, content) - VALUES (?, ?, ?, ?) - `; - + INSERT INTO messages + (message_id, sender_name, receiver_name, content) + VALUES (?, ?, ?, ?) + `; db.query(sql, [ messageId, senderName, @@ -138,6 +155,7 @@ function handleSendMessage(senderName, data) { } return; } + // 数据库确认写入后,才确认发送并推送给接收者 const senderWs = getConnection(senderName); if (senderWs) { @@ -169,36 +187,67 @@ function handleSendMessage(senderName, data) { }); } -function handleAck(receiverName, data) { +function handleAck(data, ws) { const messageId = data.messageId; - const senderName = data.senderName; - console.log( - `${receiverName} 收到消息 ${messageId},发送 ACK` - ); + // 当前 WebSocket 对应的真实用户 + const ackUser = ws.username; - // 找到原发送者 - const senderWs = getConnection(senderName); - - if (!senderWs) { - console.log( - `${senderName} 当前不在线` - ); + if (!messageId) { + console.log("ACK 缺少 messageId"); return; } - // 把 ACK 转给原发送者 - senderWs.send( - JSON.stringify({ - type: "ack", - messageId: - messageId - }) - ); + const sql = ` + SELECT sender_name, receiver_name + FROM messages + WHERE message_id = ? + `; + db.query(sql, [messageId], (error, results) => { + if (error) { + console.error("查询消息失败:", error); + return; + } - console.log( - `ACK ${messageId} 已发送给 ${senderName}` - ); + if (results.length === 0) { + console.log(`消息 ${messageId} 不存在`); + return; + } + + const message = results[0]; + // 当前用户必须是这条消息的接收者 + if (message.receiver_name !== ackUser) { + console.log( + `${ackUser} 无权确认消息 ${messageId}` + ); + return; + } + + // 原消息发送者 + const originalSender = message.sender_name; + console.log( + `${ackUser} 已收到来自 ${originalSender} 的消息 ${messageId},发送 ACK` + ); + + const senderWs = getConnection(originalSender); + if (!senderWs) { + console.log( + `${originalSender} 当前不在线` + ); + return; + } + + senderWs.send( + JSON.stringify({ + type: "ack", + messageId: messageId + }) + ); + + console.log( + `ACK ${messageId} 已发送给 ${originalSender}` + ); + }); }