Issue with WebSocket Connection in Jmix

I’m encountering an issue while developing a software application using the Jmix framework. Specifically, when I try to establish a WebSocket connection within my application code, I encounter the error message “The HTTP response from the server [200] did not permit the HTTP upgrade to WebSocket.”

Interestingly, when I use the same code and deploy it within a Spring Boot environment, everything works fine without any WebSocket connection issues.

Has anyone else experienced a similar problem while working with Jmix? If so, could you please share any insights or suggestions on how to resolve this issue?

Any help or guidance would be greatly appreciated.

Thank you in advance for your assistance.

Here is my code

ServerController.java

package com.company.jmixsocketserver.server;


import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
    public class ServerController {

    @MessageMapping("/process-message")
    @SendTo("/topic/messages")
    public OutgoingMessage processMessage(IncomingMessage incomingMessage) throws Exception{
        Thread.sleep(1000);
        return new OutgoingMessage("Hello " + incomingMessage.getName());
    }
}
WebSocketServerConfiguration.java

package com.company.jmixsocketserver.server;

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 WebSocketServerConfiguration implements WebSocketMessageBrokerConfigurer  {

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

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket-server").setAllowedOriginPatterns("*").withSockJS();
    }
}
ClientOne.java

package com.example.demo.client;

import com.example.demo.server.IncomingMessage;
import com.example.demo.server.OutgoingMessage;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.simp.stomp.StompHeaders;
import org.springframework.messaging.simp.stomp.StompSession;
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.messaging.WebSocketStompClient;

import java.lang.reflect.Type;
import java.util.concurrent.ExecutionException;

/**
 * This client send its message to server which in turn send it to common topic for communication.
 */
public class ClientOne {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        WebSocketClient client = new StandardWebSocketClient();

        WebSocketStompClient stompClient = new WebSocketStompClient(client);
        stompClient.setMessageConverter(new MappingJackson2MessageConverter());

        ClientOneSessionHandler clientOneSessionHandler = new ClientOneSessionHandler();
        ListenableFuture<StompSession> sessionAsync =
                stompClient.connect("ws://localhost:8080/websocket-server", clientOneSessionHandler);
        StompSession session = sessionAsync.get();
        session.subscribe("/topic/messages", clientOneSessionHandler);
        while (true) {
            session.send("/app/process-message", new IncomingMessage("Himanshu " + System.currentTimeMillis()));
            Thread.sleep(2000);
        }
    }
}

class ClientOneSessionHandler extends StompSessionHandlerAdapter {

    @Override
    public Type getPayloadType(StompHeaders headers) {
        return OutgoingMessage.class;
    }

    @Override
    public void handleFrame(StompHeaders headers, Object payload) {
        System.out.println("Received : " + ((OutgoingMessage) payload).getContent());
    }
}