简体   繁体   中英

websocket over spring4 and spring security SockJS /info?t=

I am trying to use websocket over spring to send and receive some strings. I used to work with an example over google but after putting all together i receive a request to an url that is not available on my contorller request.

flow/websocket/add/ info?t=1540813753999

My controller look like this :

 @Controller("webSocketController") @RequestMapping("/websocket")
 public class WebSocketController {

    @MessageMapping("/add" )
     @SendTo("/topic/showResult")
     public Result addNum(CalcInput input) throws Exception {
        Thread.sleep(2000);
         Result result = new Result(input.getNum1()+"+"+input.getNum2()+"="+(input.getNum1()+input.getNum2()));

         return result;
     }

    @RequestMapping("/start")
     public String start() {
        return "start";
    }    }

and

@Configuration
@EnableWebSocketMessageBroker
public class AppWebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

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

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/add").setAllowedOrigins("*").withSockJS();
    }

}

Javascript part :

<s:url value="/flow/websocket/add" var="sockendpoint" htmlEscape="true" />
<s:url value="/flow/websocket/topic/showResult" var="showresult" htmlEscape="true" />
<s:url value="/flow/websocket/calcApp/add" var="calcApp" htmlEscape="true" />


<script type="text/javascript">
        var stompClient = null;

        function setConnected(connected) {
            document.getElementById('connect').disabled = connected;
            document.getElementById('disconnect').disabled = !connected;
            document.getElementById('calculationDiv').style.visibility = connected ? 'visible'
                    : 'hidden';
            document.getElementById('calResponse').innerHTML = '';
        }

        function connect() {
            var socket = new SockJS('${sockendpoint}');
            //var socket = new WebSocket('${sockendpoint}');
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function(frame) {
                setConnected(true);
                console.log('Connected: ' + frame);
                stompClient.subscribe('${showresult}', function(calResult) {
                    showResult(JSON.parse(calResult.body).result);
                });
            }, function(error) {
                console.log(error);
            });
        }

        function disconnect() {
            stompClient.disconnect();
            setConnected(false);
            console.log("Disconnected");
        }

        function sendNum() {
            var num1 = document.getElementById('num1').value;
            var num2 = document.getElementById('num2').value;
            stompClient.send("${calcApp}", {}, JSON.stringify({
                'num1' : num1,
                'num2' : num2
            }));
        }

        function showResult(message) {
            var response = document.getElementById('calResponse');
            var p = document.createElement('p');
            p.style.wordWrap = 'break-word';
            p.appendChild(document.createTextNode(message));
            response.appendChild(p);
        }
    </script>

/flow is the main mapping for spring on dispatcher

Thank you in advance

The "info" endpoint is added automatically by SockJS as it is part of its protocol.

This is completely normal and the endpoint is used by the client to retrieve information about the server features.

Also, AFAIK you cannot avoid it since it is specified as part of the protocol thus mandatory.

Please refer to the Spring documentation . Link below:

https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/websocket.html

Section 22.3.1 Overview of SockJS , which explains the reason behind the endpoint.


EDIT: The real problem wasn't related with the "info" endpoint which is added automatically by the framework.

The issue is that the client was calling the STOMP server endpoint at servlet/app/stompEndpoint in the following line: <s:url value="/flow/websocket/add" var="sockendpoint" htmlEscape="true" />

The stomp server endpoint /add is not part of the App itself since a server can contain in fact multiple Apps. So, the correct path should be servlet/stompEndpoint.

<s:url value="/flow/add" var="sockendpoint" htmlEscape="true" />

Also, you can check the following Hello World example , which explains this in a more detailed way: https://spring.io/guides/gs/messaging-stomp-websocket/

It's because of the issue of /info=34424 - with 404 error - that I had to abandon it. I have Spring 4.2 in my project and many SockJS Stomp implementations usually work well with Spring Boot implementations. This implementation from Baeldung worked(for me without changing from Spring 4.2 to 5). After Using the dependencies mentioned in his blog, it still gave me ClassNotFoundError. I added the below dependency to fix it.

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>

Baeldung's implementation curiously does not make any such calls

flow/websocket/add/info?t=1540813753999

What it does (on send and receive) is below. I am only pasting it in case people well-versed with these libraries can further add insights on this forum.

 >>> SEND
destination:/app/chat
content-length:38

{"from":"nicholas","text":"try again"}

<<< MESSAGE
destination:/topic/messages
content-type:application/json;charset=UTF-8
subscription:sub-0
message-id:m3p096zk-11
content-length:53

{"from":"nicholas","text":"try again","time":"13:46"}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM