Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Docs]: How to customize WebSocket server config with STOMP over WebSocket [SPR-17514] #22046

Closed
spring-issuemaster opened this Issue Nov 18, 2018 · 7 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

spring-issuemaster commented Nov 18, 2018

Marrache Mickael opened SPR-17514 and commented

I would like to customize the Jetty WebSocketPolicy when using Spring Web Sockets with STOMP.

Here is my config class:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    public void configureWebSocketTransport(WebSocketTransportRegistration registration) {     
        registration.setMessageSizeLimit(128 * 1024);
    }
}

When setting the message size limit via the WebSocketTransportRegistration, it doesn't solve the problem since there is a text message size check made by Jetty before Spring is involved. You can see it via the following stack trace:

 

 org.eclipse.jetty.websocket.api.MessageTooLargeException: Text message size [70412] exceeds maximum size [65536]
 at org.eclipse.jetty.websocket.api.WebSocketPolicy.assertValidTextMessageSize(WebSocketPolicy.java:140) ~[websocket-api-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.websocket.common.Parser.assertSanePayloadLength(Parser.java:127) ~[websocket-common-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.websocket.common.Parser.parseFrame(Parser.java:485) ~[websocket-common-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.websocket.common.Parser.parse(Parser.java:241) ~[websocket-common-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.readParse(AbstractWebSocketConnection.java:560) [websocket-common-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:391) [websocket-common-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281) [jetty-io-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102) [jetty-io-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118) [jetty-io-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333) [jetty-util-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310) [jetty-util-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168) [jetty-util-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126) [jetty-util-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366) [jetty-util-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:762) [jetty-util-9.4.11.v20180605.jar:9.4.11.v20180605]
 at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:680) [jetty-util-9.4.11.v20180605.jar:9.4.11.v20180605]
 at java.lang.Thread.run(Thread.java:745) [na:1.8.0_101]

Therefore, I'm looking for a way to provide a custom WebSocketPolicy and pass it when the JettyRequestUpgradeStrategy is created but I can't find a way to do it.

It looks possible when the following configuration class is used but then it misses message broker configuration:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

}

 


Affects: 5.0.10

Referenced from: commits d6a5c34

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Nov 18, 2018

Marrache Mickael commented

If there is no way to do that, it is a major limitation since there would be no way to send text messages bigger than 64k.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Nov 20, 2018

Marrache Mickael commented

Any news with that ticket? We are stuck since Jetty is terminating all the websocket connections. Thanks

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Nov 20, 2018

Rossen Stoyanchev commented

The StompSubProtocolHandler has the ability to buffer and aggregate multiple WebSocket messages in order to reassemble a single STOMP frame. So the property on WebSocketTransportRegistration is for the upper limit on the size of a STOMP frame, and not for the size of individual WebSocket messages. From the Javadoc of the property:

* Configure the maximum size for an incoming sub-protocol message.
* For example a STOMP message may be received as multiple WebSocket messages
* or multiple HTTP POST requests when SockJS fallback options are in use.

See Server Configuration in the docs for how to customize Jetty's WebSocketPolicy.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Nov 20, 2018

Marrache Mickael commented

I already saw this part of the documentation (you can see that at the end of the ticket description). However, the Server Configuration mentions the use of the @EnableWebSocket annotation where I need to provide the handler myself (in the documentation example, some handler returned by _echoWebSocketHandler()_).

Could the @EnableWebSocket annotation be used along with @EnableWebSocketMessageBroker? What handler should be provided to registry.addHandler(...) when using STOMP?

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Nov 20, 2018

Rossen Stoyanchev commented

Ah, yes indeed. That's the config for raw WebSocket. The handshaker can be set in STOMP as follows:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/myEndpoint").setHandshakeHandler(handshakeHandler());
    }

    @Bean
    public DefaultHandshakeHandler handshakeHandler() {
        // ...
    }
}

I can see the docs lack this information, and the Javadoc for WebSocketTransport can also be improved.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Nov 20, 2018

Marrache Mickael commented

I just found it by searching where HandshakeHandler is used in Spring code.... Indeed, the documentation lacks this information and it's not trivial to find. Thanks for your help

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

spring-issuemaster commented Nov 21, 2018

Rossen Stoyanchev commented

Resolved with #d6a5c3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.