admin管理员组

文章数量:1278880

I am have been building the One to One Chatting Application using Spring boot and React JS. I am getting an issue when I am sending the message from one user is another. As I making one to one chatting application so I am using "/queue".

Following things are working fine:

  1. Websocket is getting connected
  2. Message is getting send to the backend.

Issue:

  1. When I send the message to Reciever, message is not reaching the receivers end.

This is the first time i am working with Websocket. I have been struggling to solve this for 3 days. I am provding the code Snippet and also the Github Link.

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., "[email protected]")

    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);
}}

FrontEnd Code:

  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.");
    }    };

Github Link:

I am have been building the One to One Chatting Application using Spring boot and React JS. I am getting an issue when I am sending the message from one user is another. As I making one to one chatting application so I am using "/queue".

Following things are working fine:

  1. Websocket is getting connected
  2. Message is getting send to the backend.

Issue:

  1. When I send the message to Reciever, message is not reaching the receivers end.

This is the first time i am working with Websocket. I have been struggling to solve this for 3 days. I am provding the code Snippet and also the Github Link.

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., "[email protected]")

    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);
}}

FrontEnd Code:

  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.");
    }    };

Github Link: https://github/AdityaVerma32/Chat-Application-Backend

Share Improve this question asked Feb 24 at 8:00 Aditya vermaAditya verma 212 bronze badges 1
  • The original issue was in the Chat-Application-Front-end project. – life888888 Commented 7 hours ago
Add a comment  | 

1 Answer 1

Reset to default 0

Quick answer:

The original issue was in the Chat-Application-Front-end project.

https://github/AdityaVerma32/Chat-Application-Front-end

Chat-Application-Front-end

src/Pages/Login.jsx

line 7: import { setUser } from '../Redux/Slices/userSlice';

change userSlice -> UserSlice

src/Redux/RootReducer.jsx

line 1: import userReducer from "./Slices/userSlice";

change userSlice -> UserSlice

add .env file

add .env file into Chat-Application-Front-end project.

.env file content

VITE_API_URL=http://localhost:8080

Run time:

Chat-Application-Backend

There is no problem with Chat-Application-Backend, no modification is required.

No changes to program logic. Only SLF4J log settings are added to increase log output.

ChatController.java

import .slf4j.Logger;
import .slf4j.LoggerFactory;
...
    private static final Logger logger = LoggerFactory.getLogger(ChatController.class);

...

    @MessageMapping("/chat") // Maps incoming messages to "/app/chat" (from frontend)
    public void sendMessage(@Payload MessageDTO messageDTO, SimpMessageHeaderAccessor headerAccessor) {

        //System.out.println(messageDTO.toString()); // Logs the received message
        logger.info("messageDTO ={} , headerAccessor = {}",messageDTO, headerAccessor);
        String receiver = messageDTO.getReceiverEmail(); // Extracts receiver's email
...

Output:

2025-03-06T15:49:48.506+08:00  INFO 19283 --- [ChatApplication] [nio-8080-exec-7] c.C.C.Config.WebSocketInterceptor        : query = [email protected]
2025-03-06T15:49:48.506+08:00  INFO 19283 --- [ChatApplication] [nio-8080-exec-7] c.C.C.Config.WebSocketInterceptor        : User Connected: [email protected]
2025-03-06T15:49:48.508+08:00  INFO 19283 --- [ChatApplication] [nio-8080-exec-7] c.C.C.Config.WebSocketInterceptor        : >>> afterHandshake
2025-03-06T15:49:48.519+08:00  INFO 19283 --- [ChatApplication] [tboundChannel-8] c.C.C.Events.WebSocketEventListener      : event = SessionConnectedEvent[GenericMessage [payload=byte[0], headers={simpMessageType=CONNECT_ACK, simpConnectMessage=GenericMessage [payload=byte[0], headers={simpMessageType=CONNECT, stompCommand=CONNECT, nativeHeaders={accept-version=[1.2,1.1,1.0], heart-beat=[10000,10000]}, simpSessionAttributes={[email protected]}, simpHeartbeat=[J@2079b8bc, simpSessionId=v1mgq1i2}], simpSessionId=v1mgq1i2}]]
2025-03-06T15:49:48.599+08:00  INFO 19283 --- [ChatApplication] [nio-8080-exec-9] c.C.C.Controllers.UserController         : currrentUser = LoginUser{email='ZZZ@localhost'}
2025-03-06T15:49:53.448+08:00  INFO 19283 --- [ChatApplication] [nio-8080-exec-5] c.C.C.Controllers.UserController         : currrentUser = LoginUser{email='[email protected]'}
2025-03-06T15:49:53.565+08:00  INFO 19283 --- [ChatApplication] [nio-8080-exec-6] c.C.C.Controllers.UserController         : currrentUser = LoginUser{email='ZZZ@localhost'}
2025-03-06T15:49:58.604+08:00  INFO 19283 --- [ChatApplication] [nio-8080-exec-7] c.C.C.Controllers.UserController         : currrentUser = LoginUser{email='[email protected]'}

本文标签: