Allen Alex Abraham
Allen Alex Abraham

Reputation: 1

Can't get Stomp JS client to subscribe to my backend websocket built using spring boot

I am trying to build a chat application where the frontend is built using HTML, CSS, JS, and the websockets handling in the backend is built using Java spring boot. The below is my client code.

document.addEventListener("DOMContentLoaded", ()=>{
    console.log("HOWDY!");
    var client = null;
    const user = {
        id: window.localStorage.getItem("id"),
        to: parseInt(window.location.href.split("?")[1].split("=")[1])
    }

    const link = "/user/"+user.id+"/queue/message";
    const messageQueue = "/user/queue/message";
    const subscribeQueue = "/queue/message"
    const sendLink = "/app/message";
    var url = "ws://localhost:8080/textr-socket";

    async function getChats(){
        try {
            if(localStorage.getItem("token") == null){
                window.location.href = window.location.href.split("/")[0] + "/index.html"
                return;
            }
            const response = await axios.get('http://localhost:8080/api/v1/secure/message/'+user.id+'/'+user.to, {
                headers: {
                    'Authorization': 'Bearer '+localStorage.getItem("token")
                }
            });
            const messages = response.data.data;
            const textsDiv = document.getElementById('texts');
            textsDiv.innerHTML = '';
            messages.forEach(message => {
                const data = fetchMessageHTML(message.message, window.localStorage.getItem("id"), message.sendTo);
                textsDiv.appendChild(data);
            });           
        } catch (error) {
            console.error('Error fetching messages:', error);
        }
    }
    function onMessage(notification){
        console.log("Inside subscription");
        console.log("SUPER SUBSCRIPTION!", notification)
        console.log("Subscribed")
        const receivedNotification = JSON.parse(notification.body);
        console.log("received out",receivedNotification);
        if(receivedNotification.receiverId == user.id){
            console.log("received in",receivedNotification);
            getChats();
        }
    }
    function onerror(error){
        console.log("The error is ", error);
    }
    function onConnected(){
        console.log("connected now subscribing");
        client.subscribe(
            link,
            onMessage,
            // onerror,
            {id:"sub-"+user.id}

        );
    }

    getChats();
    client =  Stomp.client(url);
    client.heartbeat.outgoing = 100; // client will send heartbeats every 20000ms
    client.heartbeat.incoming = 100;
    client.reconnect_delay = 100;
    client.connect({}, onConnected);

    document.getElementById("submit-button").addEventListener("click",function (){
        const data = document.getElementById("submit-text").value;
        const messageData = {
            from:user.id,
            sendTo:user.to,
            message: data
        }
        client.send(sendLink, {}, JSON.stringify(messageData));
        getChats();
    });
    
    function fetchMessageHTML(messageText,from, to){
        const messageContainer = document.createElement("div");
        const message = document.createElement("p");
        message.innerText = messageText;
        if(from==to){
            message.setAttribute("class", "red");
        }
        messageContainer.appendChild(message);
        return messageContainer;
    }

});

Now the issue I'm facing is that my client is able to send messages to another person. there isn't any issues in that but when it comes to receiving messages my client is subscribing to the server but it is not receiving the messages/notifications.

And this is my websocket config

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void  configureMessageBroker(MessageBrokerRegistry config){
        config.enableSimpleBroker("/queue");
        config.setApplicationDestinationPrefixes("/app");
        config.setUserDestinationPrefix("/user");
    }


    @Override
    public void  registerStompEndpoints(StompEndpointRegistry registry){
        registry.addEndpoint("/textr-socket")
                .setAllowedOrigins("*");
    }
    @Override
    public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
        return true;
    }

}

And this is my chat controller

@RestController
@CrossOrigin(origins = "*")
public class ChatController {
    @Autowired
    MessageService messageService;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    MessageRepository messageRepository;

    @Autowired
    UserRepository userRepository;




//    @MessageMapping("/messages")
//    @SendTo("/topic/messages")
//    public List<MessageRecord> getMessagesSocket(Long from, Long to){
//        List<MessageRecord> messages = messageService.getMessages(from, to);
//
//        // Send messages to the specified destination
//        messagingTemplate.convertAndSend("/topic/messages", messages);
//        return messages;
//    }

    @MessageMapping("/message")
    public void sendMessage(@Payload MessageRecord messageRecord) throws CustomisedException {
        User from = userRepository.getUserById(messageRecord.from());
        User toSendTo = userRepository.getUserById(messageRecord.sendTo());
        if(toSendTo == null){
            throw new CustomisedException("User doesn't exist!");
        }
//        User user = Utils.getCurrentUser();
        Message message = Message.builder()
                .senderId(from)
                .createdOn(new Timestamp(System.currentTimeMillis()))
                .receiverId(userRepository.getUserById(messageRecord.sendTo()))
                .message(messageRecord.message())
                .status(MessageStatus.SENT)
                .build();
        Message savedMessage = messageRepository.save(message);
        System.out.println("WE ARE SENDING TO "+String.valueOf(savedMessage.getReceiverId().getId()));
        messagingTemplate.convertAndSendToUser(String.valueOf(savedMessage.getReceiverId().getId()),
                "/queue/message",
                MessageNotification.builder()
                        .receiverId(savedMessage.getReceiverId().getId())
                        .senderId(savedMessage.getSenderId().getId())
                        .build().toString());
    }
}

I am attatching logs of the client websites (sender side) console logs

enter image description here

And this is the console logs of the receiver clients website

enter image description here

It's been a while that I have been stuck with this problem and help would be highly appreciated

I have tried a lot of stuff mentioned in the docs an all const link = "/user/"+user.id+"/queue/message"; const messageQueue = "/user/queue/message";

Insted of subscribing to "link" link I had also tried subscribing to messageQue because I hear that stomp will automatically add the user id to it.

But none of this worked.

Upvotes: 0

Views: 61

Answers (0)

Related Questions