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

Websocket compression, disable 9.4 #1341

Closed
faljse opened this issue Feb 18, 2017 · 8 comments
Closed

Websocket compression, disable 9.4 #1341

faljse opened this issue Feb 18, 2017 · 8 comments

Comments

@faljse
Copy link

faljse commented Feb 18, 2017

I´d like to disable websocket compression to reduce cpu consumption.

In 9.3 it was possible via:

WebSocketUpgradeFilter filter  =  (WebSocketUpgradeFilter)context.getAttribute("org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter");
filter.getFactory().getExtensionFactory().unregister("permessage-deflate");

Is there a way to do this in jetty 9.4?

@joakime
Copy link
Contributor

joakime commented Feb 19, 2017

You can still do that, but only after the server has started.
Consider setting that up on Servlet.init() or if you are using embedded jetty, start the server first, then get the context attribute.

faljse added a commit to faljse/webyoucam that referenced this issue Feb 19, 2017
remove compression filter after server.start:
jetty/jetty.project#1341
@faljse
Copy link
Author

faljse commented Feb 19, 2017

I moved the code after server.start(), but it doesn`t make a difference
My context contains those 3 Objects after server.start:

0 = {ConcurrentHashMap$MapEntry@3421} "wsSessions" -> (custom, application code)
1 = {ConcurrentHashMap$MapEntry@3422} "org.eclipse.jetty.server.Executor" -> "qtp140799417{STARTED,8<=8<=200,i=2,q=0}"
2 = {ConcurrentHashMap$MapEntry@3423} "javax.websocket.server.ServerContainer" -> 

My server init code is pretty basic, it is available here.

@faljse
Copy link
Author

faljse commented Feb 23, 2017

I solved it; replaced configureContext with():

public static org.eclipse.jetty.websocket.jsr356.server.ServerContainer configureContext(ServletContextHandler context) throws ServletException {
    NativeWebSocketConfiguration nativeWebSocketConfiguration = NativeWebSocketServletContainerInitializer.getDefaultFrom(context.getServletContext());
    nativeWebSocketConfiguration.getFactory().getExtensionFactory().unregister("permessage-deflate");
    org.eclipse.jetty.websocket.jsr356.server.ServerContainer jettyContainer = new org.eclipse.jetty.websocket.jsr356.server.ServerContainer(nativeWebSocketConfiguration, context.getServer().getThreadPool());
    context.addBean(jettyContainer);
    context.setAttribute(javax.websocket.server.ServerContainer.class.getName(), jettyContainer);
    if(WebSocketServerContainerInitializer.isEnabledViaContext(context.getServletContext(), "org.eclipse.jetty.websocket.jsr356.addDynamicFilter", true)) {
        WebSocketUpgradeFilter.configureContext(context);
    }
    return jettyContainer;
}

@faljse faljse closed this as completed Feb 23, 2017
@joakime
Copy link
Contributor

joakime commented Feb 23, 2017

That is needlessly complicated.

The WebSocketUpgradeFilter can be configured directly.

// Server init code
WebSocketUpgradeFilter wsuf = WebSocketUpgradeFilter.configureContext(context);
wsuf.getFactory().getExtensionFactory().unregister("permessage-deflate");

or, from ...

// Override this method, part of WebSocketHandler, or WebSocketServlet
public void configure(WebSocketServletFactory factory)
{
  factory.getExtensionFactory().unregister("permessage-deflate");
}

or, strip it from the upgrade request from the client ...

// Override this method from WebSocketCreator
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
{
  List<ExtensionConfig> negotiated = new ArrayList<>();
  for(ExtensionConfig config: req.getExtensions())
  {
    if (!config.getName().equals("permessage-deflate"))
    {
      negotiated.add(config);
    }
  }
  resp.setExtensions(negotiated);
  // rest of your create impl here
  return endpoint;
}

@joakime
Copy link
Contributor

joakime commented Feb 23, 2017

You can even register a ServletContextListener to do it.

public class AdjustWebSocket implements ServletContextListener
{
  public void contextInitialized(ServletContextEvent sce)
  {
    NativeWebSocketConfiguration configuration = (NativeWebSocketConfiguration) sce.getServletContext().getAttribute(NativeWebSocketConfiguration.class.getName());
    configuration.getFactory().getExtensionFactory().unregister("permessage-deflate");
  }
  public void contextDestroyed(ServletContextEvent sce)
  {
  }
}

@joakime
Copy link
Contributor

joakime commented Feb 23, 2017

You can even use the JSR356 ServerEndpointConfig.Configurator to strip it from the client.

public class NoExtensionsConfigurator extends ServerEndpointConfig.Configurator
{
    @Override
    public List<Extension> getNegotiatedExtensions(List<Extension> installed, 
                     List<Extension> requested)
    {
        return Collections.emptyList();
    }
}

@faljse
Copy link
Author

faljse commented Feb 23, 2017

Wow, thanks!
Yes, it did seem complicated, but well.. i couldn't figure it out :)

My init code, including ServerContainer changes is now:

WebSocketUpgradeFilter wsuf = WebSocketUpgradeFilter.configureContext(context);
wsuf.getFactory().getExtensionFactory().unregister("permessage-deflate");
ServerContainer sc= new ServerContainer(wsuf.getConfiguration(), server.getThreadPool());
context.addBean(sc);

@joakime
Copy link
Contributor

joakime commented Feb 23, 2017

Don't initialize the ServerContainer yourself, that won't work reliably. (esp knowing what's coming with the javax.websocket 1.1 support soon)

Why are you using JSR356? It's a very naive API, and your needs have already outgrown it (as evidenced by you need to configure things that are not exposed by the JSR356 API). Would encourage you to look at / use the Native WebSocket API in Jetty, as things get much simpler, and far more powerful (configurable).

If you need to stick with JSR356, then use the ServletContextListener approach, it will be the most reliable, as it configures the container after it has has started, and before any connections have been attempted.

viv added a commit to viv/Openfire that referenced this issue May 18, 2023
Correct configuration of websocket compression. Compression is provided out of the box by Jetty's `permessage-deflate` extension.

Previously Openfire was registering the `permessage-deflate` extension, I assume this was attempting to enable websocket compression.

Presently, websocket compression is enabled by default in Jetty. So the correct way to control websocket compression is to disable the `permessage-deflate` extension when compression is not wanted:
jetty/jetty.project#1341
viv added a commit to viv/Openfire that referenced this issue Sep 4, 2023
Correct configuration of websocket compression. Compression is provided out of the box by Jetty's `permessage-deflate` extension.

Previously Openfire was registering the `permessage-deflate` extension, I assume this was attempting to enable websocket compression.

Presently, websocket compression is enabled by default in Jetty. So the correct way to control websocket compression is to disable the `permessage-deflate` extension when compression is not wanted:
jetty/jetty.project#1341
guusdk pushed a commit to igniterealtime/Openfire that referenced this issue Sep 7, 2023
Correct configuration of websocket compression. Compression is provided out of the box by Jetty's `permessage-deflate` extension.

Previously Openfire was registering the `permessage-deflate` extension, I assume this was attempting to enable websocket compression.

Presently, websocket compression is enabled by default in Jetty. So the correct way to control websocket compression is to disable the `permessage-deflate` extension when compression is not wanted:
jetty/jetty.project#1341
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants