使用Spring WebSocket开发一对一聊天应用:消息无法送达接收端
一对一聊天应用WebSocket消息无法送达接收端问题
我正在用Spring Boot和ReactJS开发一对一聊天应用,采用/queue实现一对一聊天逻辑,但遇到消息从发送方到接收方无法送达的问题。
正常功能
- WebSocket连接正常
- 消息可成功发送至后端
存在的问题
- 发送给接收方的消息无法送达接收端
这是我第一次使用WebSocket,已经为此困扰3天,以下是相关代码片段:
WebSocketConfiguration
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfigure implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registery) { registery.addEndpoint("/ws") .setAllowedOrigins("http://localhost:5173") .addInterceptors(new WebSocketInterceptor()) .withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry registery) { registery.enableSimpleBroker("/queue"); registery.setApplicationDestinationPrefixes("/app"); registery.setUserDestinationPrefix("/user"); }}
WebSocketInterceptor
public class WebSocketInterceptor implements HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { // Extract email from request (Assume it's passed as a query param) // Extract email from query params instead of headers URI uri = request.getURI(); String query = uri.getQuery(); // Get query string (e.g., "user-email=aditya@gmail.com") if (query != null && query.contains("user-email=")) { String email = query.split("user-email=")[1]; // Extract email System.out.println("✅ User Connected: " + email); attributes.put("user-email", email); // Store email in session attributes } else { System.out.println("❌ No email found in query params"); } return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { }}
Chat Controller
@Controller public class ChatController { private final SimpMessagingTemplate simpMessagingTemplate; private final ChatMessageService chatMessageService; public ChatController(SimpMessagingTemplate simpMessagingTemplate, ChatMessageService chatMessageService) { this.simpMessagingTemplate = simpMessagingTemplate; this.chatMessageService = chatMessageService; } /** * Receives a message from a user, stores it in the database, * and sends it in real-time to the recipient only if they have that chat open. */ @MessageMapping("/chat") public void sendMessage(@Payload MessageDTO messageDTO, SimpMessageHeaderAccessor headerAccessor) { System.out.println(messageDTO.toString()); String receiver = messageDTO.getReceiverEmail(); System.out.println(" Receiver is : " + receiver); String senderEmail = (String) headerAccessor.getSessionAttributes().get("user-email"); if (senderEmail == null) { System.out.println("❌ Error: Sender email not found in session!"); return; } MessageModel messageModel = chatMessageService.saveMessage(messageDTO); simpMessagingTemplate.convertAndSendToUser(receiver, "/queue/messages", messageModel); } /** * Retrieves chat history between two users when a user opens a chat room. */ @GetMapping("/chat/history/{user1}/{user2}") @ResponseBody public ResponseEntity<ApiResponse> getChatHistory(@PathVariable String user1, @PathVariable String user2) { return chatMessageService.getChatHistory(user1, user2); }}
前端代码
useEffect(() => { if (!currentUserEmail || !currentUserName || !currentUserPhone || !currentUserId) { navigate("/"); } // ================== Websocket ================== const socket = new SockJS(`http://localhost:8080/ws?user-email=${encodeURIComponent(currentUserEmail)}`); const stompClient = new Client({ webSocketFactory: () => socket, // debug: (str) => { // console.log(str); // }, reconnectDelay: 5000, // heartbeatIncoming: 4000, // heartbeatOutgoing: 4000, onConnect: () => { console.log("Connected to WebSocket"); // Subscribe to the user-specific queue for receiving messages stompClient.subscribe("/user/queue/messages", (message) => { const receivedMessage = JSON.parse(message.body); console.log("Message received: ", receivedMessage); }); }, }); // Connect WebSocket stompClient.activate(); setStompClient(stompClient); // ================== Websocket ================== fetchAllUsers(); }, []) const sendMessage = (message, toUser) => { if (stompClient && stompClient.connected) { const msgObject = { senderEmail: currentUserEmail, receiverEmail: toUser.email, content: message, timestamp: new Date(), }; stompClient.publish({ destination: "/app/chat", body: JSON.stringify(msgObject), }); setMessages([...messages, msgObject]); console.log("Message sent:", msgObject); } else { console.error("STOMP client is not connected."); } };
内容的提问来源于stack exchange,提问作者Aditya verma
相关产品推荐
相关产品推荐

