Websocket Read Timeout when using Spring Websockets without SocksJS Fallback

Issue #63 closed
Blasius Riz created an issue

Hi Peter,

not really sure if this a bug at all, so I filed this under enhancement. Maybe you can give some pointers on how to tackle the debugging. We are using the Spring Framework for Websockets and STOMP as subprotocol. As I gather from this document https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/websocket.html, Spring either provides their Spring Web socket API or a Fallback through SocksJS.

I successfully built a load test using your nice Websocket samplers using Springs SocksJS Fallback on the server side. It stops working though, when using the Spring Websocket API directly on the server side. A connection is created and I can see that the server is answering with the status 101 and the connection is upgraded. But when sending a text frame, nothing seems to register on the server side and reading a text frame results in a timeout, despite the connection being active. Maybe my understanding of websockets is limited, but both the Spring Websocket API and the SocksJS Fallback should be using websockets in the background when I choose Websocket as protocol. I don't see at the moment why one works and the other doesn't.

In case you are interested and would like to investigate as well, a sample server project can be found here: https://github.com/spring-guides/gs-messaging-stomp-websocket/tree/master/complete For the client side, I isolated your Websocket Client in a separate project for testing purposes.

In the class WebsocketConfig in the server project, using this setting enables SocksJS support:

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

On the client side, this code produces a connection and an answer from the server:

URL url =  new URL("http","localhost", 8080, "/ws/1/1/websocket");
WebSocketClient webSocketClient = new WebSocketClient(url);
WebSocketClient.HttpResult result = webSocketClient.connect();
webSocketClient.sendTextFrame("[\"CONNECT\\n\\n\\u0000\"]");
Frame frame = webSocketClient.receiveFrame(3000);

When using this setting on the server side:

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

and using this code on the client side, I get a connection but nothing is received on the server side:

URL url =  new URL("http","localhost", 8080, "/ws");
WebSocketClient webSocketClient = new WebSocketClient(url);
WebSocketClient.HttpResult result = webSocketClient.connect();
webSocketClient.sendTextFrame("[\"CONNECT\\n\\n\\u0000\"]");
Frame frame = webSocketClient.receiveFrame(3000);

Of course we could just use the SocksJS Fallback and support old browsers as well in the process, but still it bugs me why sending and receiving doesn't seem to work when using the Spring Websocket API

Thanks and best regards,

Blasius

Comments (5)

  1. Blasius Riz reporter

    After wadding through the Spring code base, I found out that the Spring Websocket Stomp Decoder and the SockJS Stomp Decoder expect text frames in different formats. Unfortunately, the Spring Stomp Decoder fails silently on normal debug levels, so I didn't spot the error immediately. If anyone else should run into this issue, this is how frames should look like:

    SocksJS:

    ["CONNECT\n\n\u0000"]

    Spring Websocket (and probably other implementations as well):

    CONNECT\n\n\u0000

  2. Peter Doornbosch repo owner

    Hi Blasius,

    Thanks for your comments and especially for sharing the solution to your problem ;-).

    Regards, Peter

  3. Log in to comment