diff --git a/backend/src/main/java/com/openisle/service/MessageService.java b/backend/src/main/java/com/openisle/service/MessageService.java index aec7de896..2f451e46b 100644 --- a/backend/src/main/java/com/openisle/service/MessageService.java +++ b/backend/src/main/java/com/openisle/service/MessageService.java @@ -141,35 +141,30 @@ public class MessageService { conversationRepository.save(conversation); MessageDto messageDto = toDto(message); - String conversationDestination = "/topic/conversation/" + conversation.getId(); - for (MessageParticipant participant : conversation.getParticipants()) { - if (participant.getUser().getId().equals(senderId)) continue; - - long unreadCount = getUnreadMessageCount(participant.getUser().getId()); - long channelUnread = getUnreadChannelCount(participant.getUser().getId()); + // Build participant payloads once to avoid duplicate broadcasts + java.util.List> participantInfos = conversation.getParticipants().stream() + .filter(p -> !p.getUser().getId().equals(senderId)) + .map(p -> { + Map info = new HashMap<>(); + info.put("userId", p.getUser().getId()); + info.put("username", p.getUser().getUsername()); + info.put("unreadCount", getUnreadMessageCount(p.getUser().getId())); + info.put("channelUnread", getUnreadChannelCount(p.getUser().getId())); + return info; + }).collect(Collectors.toList()); - Map combinedPayload = new HashMap<>(); - combinedPayload.put("message", messageDto); + Map conversationInfo = new HashMap<>(); + conversationInfo.put("id", conversation.getId()); + conversationInfo.put("participants", participantInfos); - Map conversationInfo = new HashMap<>(); - conversationInfo.put("id", conversation.getId()); - conversationInfo.put("participants", conversation.getParticipants().stream() - .filter(item -> participant.getUser().getId().equals(item.getUser().getId())) - .map(p -> { - Map participantInfo = new HashMap<>(); - participantInfo.put("userId", p.getUser().getId()); - participantInfo.put("username", p.getUser().getUsername()); - return participantInfo; - }).collect(Collectors.toList())); + Map combinedPayload = new HashMap<>(); + combinedPayload.put("message", messageDto); + combinedPayload.put("conversation", conversationInfo); + combinedPayload.put("senderId", senderId); - combinedPayload.put("conversation", conversationInfo); - combinedPayload.put("senderId", senderId); - combinedPayload.put("unreadCount", unreadCount); - combinedPayload.put("channelUnread", channelUnread); - - notificationProducer.sendNotification(new MessageNotificationPayload(participant.getUser().getUsername(), combinedPayload)); - } + // Use sender's username for sharding; only one notification is needed + notificationProducer.sendNotification(new MessageNotificationPayload(sender.getUsername(), combinedPayload)); return message; } diff --git a/websocket_service/src/main/java/com/openisle/websocket/listener/NotificationListener.java b/websocket_service/src/main/java/com/openisle/websocket/listener/NotificationListener.java index 205d42c0c..fa18536f3 100644 --- a/websocket_service/src/main/java/com/openisle/websocket/listener/NotificationListener.java +++ b/websocket_service/src/main/java/com/openisle/websocket/listener/NotificationListener.java @@ -79,15 +79,16 @@ public class NotificationListener { messagingTemplate.convertAndSend(userDestination, messageObj); log.info("Message notification sent to destination: {}", userDestination); - // 发送未读数量 - if (payloadMap.containsKey("unreadCount")) { - messagingTemplate.convertAndSendToUser(participantUsername, "/queue/unread-count", payloadMap.get("unreadCount")); + // 优先从 participant 中获取未读信息,兼容旧格式 + Object unreadCount = participant.getOrDefault("unreadCount", payloadMap.get("unreadCount")); + if (unreadCount != null) { + messagingTemplate.convertAndSendToUser(participantUsername, "/queue/unread-count", unreadCount); log.info("Sent unread count to user {} via /user/{}/queue/unread-count", participantUsername, participantUsername); } - // 发送频道未读数量(如果有) - if (payloadMap.containsKey("channelUnread")) { - messagingTemplate.convertAndSendToUser(participantUsername, "/queue/channel-unread", payloadMap.get("channelUnread")); + Object channelUnread = participant.getOrDefault("channelUnread", payloadMap.get("channelUnread")); + if (channelUnread != null) { + messagingTemplate.convertAndSendToUser(participantUsername, "/queue/channel-unread", channelUnread); log.info("Sent channel-unread to {}", participantUsername); } }