完善websocket消息确认机制
This commit is contained in:
+90
-41
@@ -43,6 +43,7 @@ function initWebSocket(server) {
|
||||
console.log("WebSocket用户:", user);
|
||||
|
||||
const username = user.username;
|
||||
ws.username = username;
|
||||
// 保存连接
|
||||
addConnection(username, ws);
|
||||
|
||||
@@ -54,20 +55,21 @@ function initWebSocket(server) {
|
||||
|
||||
// 接收客户端消息
|
||||
ws.on("message", (message) => {
|
||||
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}`
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user