Spring boot websocket chat(stomp) receive function didnt works

42 Views Asked by At

I'm currently implementing websockets with stomp However, the send function works on the frontend, but I can't receive it on the server side.

SEND destination:/app/chatAddUser content-length:15

package com.lsm.backend.config creating questions in the future, there will be only one body field, but for best results remember to include both a description of your problem and what you’ve tried.;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").setAllowedOrigins("http://localhost:3000").withSockJS();
    }
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/app");
        registry.enableSimpleBroker("/queue", "/topic");

    }

}
package com.lsm.backend.controller;

import com.lsm.backend.model.ChatMessageDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ChatController {
    @Autowired
    private SimpMessageSendingOperations messagingTemplate;
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @MessageMapping("/app/chatSendMessage")
    public void sendMessage(@Payload ChatMessageDTO chatMessageDTO) {
        logger.info("Received message from client: " + chatMessageDTO);
        messagingTemplate.convertAndSend("/topic/public", chatMessageDTO);
    }
    @MessageMapping("/app/chatAddUser")
    public void addUser(@Payload ChatMessageDTO chatMessageDTO) {
        logger.info("joined", chatMessageDTO);
        messagingTemplate.convertAndSend("/topic/public", chatMessageDTO); 
    }
}

package com.lsm.backend.model;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ChatMessageDTO {
    private MessageType type;
    private String content;
    private String sender;
    public enum MessageType{
        CHAT,
        JOIN,
        LEAVE
    }


}

This is my backend source code. its done setting up CORS CSRF for this project. I can see that the send function is executing on the front end, but I don't see any logs on the server side, and of course I don't get any receive on the frontend.

I've tried fixes from various github repositories, but I still have the same problem.

1

There are 1 best solutions below

0
Malvin Lok On

Upon inspecting your code, the methods annotated with @MessageMapping should map to the destination without the application destination prefixes according to the configureMessageBroker configuration.

The problem here is with your @MessageMapping annotation parameters. They should not contain the application prefix which you have defined as "/app" via setApplicationDestinationPrefixes("/app") in the config.

Hence, your controller should look like this:

@RestController
public class ChatController {
    @Autowired
    private SimpMessageSendingOperations messagingTemplate;
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @MessageMapping("/chatSendMessage")
    public void sendMessage(@Payload ChatMessageDTO chatMessageDTO) {
        logger.info("Received message from client: " + chatMessageDTO);
        messagingTemplate.convertAndSend("/topic/public", chatMessageDTO);
    }

    @MessageMapping("/chatAddUser")
    public void addUser(@Payload ChatMessageDTO chatMessageDTO) {
        logger.info("Joined: " + chatMessageDTO);
        messagingTemplate.convertAndSend("/topic/public", chatMessageDTO);
    }
}

In this example, I removed "/app" prefix from @MessageMapping("/app/chatSendMessage") and @MessageMapping("/app/chatAddUser") so they are now @MessageMapping("/chatSendMessage") and @MessageMapping("/chatAddUser") respectively.

When you send the data through WebSocket, you should send it to "/app/chatSendMessage" or "/app/chatAddUser". Based on your configuration, the "/app" prefix will be removed and the remaining destination ("/chatAddUser" or "/chatSendMessage") will be used to route to the corresponding method.