I am trying to enable Websocket-level compression. I have WebSocket configuration as shown below. I use "extends WebSocketMessageBrokerConfigurationSupport" approach.
I incorporated the recipe from Spring Websocket Configuration: using WebSocketMessageBrokerConfigurationSupport and WebSocketConfigurer together - how? and Spring STOMP Websockets: any way to enable permessage-deflate on server side? to add handshakeHandler()
PROBLEM: in logs I see that my handshakeHandler is called, but I have added logging to JettyRequestUpgradeStrategy in Spring (using local custom build) that outputs the extensions. I found that the JettyRequestUpgradeStrategy is called also from unknown, different places and these calls do not have needed extension. I suspect that my HandshakeHandler is not really used in actual connection and gets overridden by default method somewhere.
Wireshark shows that messages are not compressed and Swicthing Protocols HTTP 101 package does not show Sec-WebSocket-Extensions: permessage-deflate header that suppose to indicate compression.
Correct call
o.s.w.s.m.SubProtocolWebSocketHandler : Add protocol handler StompSubProtocolHandler[v10.stomp, v11.stomp, v12.stomp]
WebSocketConfig --- Handshake handler called
o.s.w.s.s.j.JettyRequestUpgradeStrategy : Factory >>{
permessage-compress=class org.eclipse.jetty.websocket.common.extensions.compress.PerMessageDeflateExtension,
fragment=class org.eclipse.jetty.websocket.common.extensions.fragment.FragmentExtension,
deflate-frame=class org.eclipse.jetty.websocket.common.extensions.compress.DeflateFrameExtension,
identity=class org.eclipse.jetty.websocket.common.extensions.identity.IdentityExtension,
x-webkit-deflate-frame=class org.eclipse.jetty.websocket.common.extensions.compress.XWebkitDeflateFrameExtension,
permessage-deflate=class org.eclipse.jetty.websocket.common.extensions.compress.PerMessageDeflateExtension}
Some later calls, right after previous ones:
o.s.w.s.m.SubProtocolWebSocketHandler : Add protocol handler StompSubProtocolHandler[v10.stomp, v11.stomp, v12.stomp]
o.s.w.s.m.SubProtocolWebSocketHandler : Add protocol handler StompSubProtocolHandler[v10.stomp, v11.stomp, v12.stomp]
o.s.w.s.s.j.JettyRequestUpgradeStrategy : Factory >>{fragment=class org.eclipse.jetty.websocket.common.extensions.fragment.FragmentExtension,
deflate-frame=class org.eclipse.jetty.websocket.common.extensions.compress.DeflateFrameExtension,
identity=class org.eclipse.jetty.websocket.common.extensions.identity.IdentityExtension,
x-webkit-deflate-frame=class org.eclipse.jetty.websocket.common.extensions.compress.XWebkitDeflateFrameExtension,
permessage-deflate=class org.eclipse.jetty.websocket.common.extensions.compress.PerMessageDeflateExtension}
o.s.w.s.s.j.JettyRequestUpgradeStrategy : Factory >>{
fragment=class org.eclipse.jetty.websocket.common.extensions.fragment.FragmentExtension,
deflate-frame=class org.eclipse.jetty.websocket.common.extensions.compress.DeflateFrameExtension,
identity=class org.eclipse.jetty.websocket.common.extensions.identity.IdentityExtension,
x-webkit-deflate-frame=class org.eclipse.jetty.websocket.common.extensions.compress.XWebkitDeflateFrameExtension,
permessage-deflate=class org.eclipse.jetty.websocket.common.extensions.compress.PerMessageDeflateExtension}
and here I do not see permessage-compress in use.
Note that in all cases there is similar permessage-deflate extension that might, in fact, be some sort of parallel option. I'd like to understand what is the difference between permessage-deflate and permessage-compress extensions.
Here's how I configure the WebSockets in Spring.
@Configuration
@EnableScheduling
public class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport {
@Bean
public DefaultHandshakeHandler handshakeHandler() {
LOGGER.info("Handshake handler called");
WebSocketServerFactory factory = new WebSocketServerFactory();
// add the "permessage-compress" Websocket extension
factory.getExtensionFactory()
.register("permessage-compress", PerMessageDeflateExtension.class);
return new DefaultHandshakeHandler(new JettyRequestUpgradeStrategy(factory));
}
@Override
protected void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/api")
.setHandshakeHandler(handshakeHandler())
.setAllowedOrigins("*")
.withSockJS();
registry.addEndpoint(USER_ENDPOINT)
.setHandshakeHandler(handshakeHandler())
.setAllowedOrigins("*")
.withSockJS();
registry.addEndpoint(ORDER_ENDPOINT)
.setHandshakeHandler(handshakeHandler())
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public WebSocketHandler subProtocolWebSocketHandler() {
customSubProtocolWebSocketHandler = new CustomSubProtocolWebSocketHandler(clientInboundChannel(), clientOutboundChannel(), sessionHandler);
return customSubProtocolWebSocketHandler;
}
}