blacktide
blacktide

Reputation: 12076

Setting Servlet Context Initialization Parameters for Tomcat

I have a Grails application that has a simple Websocket endpoint, shown here:

@WebListener
@ServerEndpoint("/chatEndpoint/{chatId}")
public class WebsocketChatroomEndpoint implements ServletContextListener {

  static ConfigObject config

  @Override
  public void contextInitialized(ServletContextEvent sce) {
    ServletContext servletContext = sce.servletContext
    ServerContainer serverContainer = servletContext.getAttribute("javax.websocket.server.ServerContainer")
    try {
      ApplicationContext ctx = (ApplicationContext) servletContext.getAttribute(GA.APPLICATION_CONTEXT)
      config = ctx.grailsApplication.config
      serverContainer.defaultMaxSessionIdleTimeout = 0
    } catch (IOException e) {
      log.error(e.message, e)
    }
  }

  @Override
  public void contextDestroyed(ServletContextEvent servletContextEvent) {
  }

  @OnOpen
  public void onOpen(Session userSession, @PathParam("chatId") String chatId) {
    // Do some stuff
  }

  @OnMessage
  public String onMessage(String message, Session userSession) throws IOException {
    // Handle message received
  }

  @OnClose
  public void onClose(Session userSession, CloseReason reason) {
    // Handle close
  }

  @OnError
  public void onError(Throwable t) {
    // Handle error
  }
}

The endpoint works fine, but the problem I am running into is that when deploying to Tomcat 8, idle connections are disconnected after 60 seconds.

The Tomcat Websocket How-To states that this value can be changed by setting the following servlet context initialization parameter: org.apache.tomcat.websocket.executorKeepAliveTimeSeconds.

I've set this parameter in the web.xml file like so:

<context-param>
    <param-name>org.apache.tomcat.websocket.executorKeepAliveTimeSeconds</param-name>
    <param-value>1000</param-value>
</context-param>

And, when I access the parameter in the contextInitialized method of my Listener, the value is set properly.

@Override
public void contextInitialized(ServletContextEvent sce) {
  ServletContext servletContext = sce.servletContext

  // Logs "1000"
  log.debug(servletContext.getInitParameter("org.apache.tomcat.websocket.executorKeepAliveTimeSeconds"))
}

The problem is that the endpoint still times out after 60 seconds, no matter what I set this value to. I've tried setting the value inside of Tomcat's context.xml file, as well as programmatically setting it in my listener. Does anyone have any idea how to override Tomcat's default value of 60 seconds for this?

Upvotes: 2

Views: 2863

Answers (1)

blacktide
blacktide

Reputation: 12076

I've resolved the issue, and I was obviously out of my mind when troubleshooting this.

I have nginx reverse-proxying connections to Tomcat. Tomcat was setting the value properly, but the proxy_read_timeout in nginx defaults to 60 seconds. Increasing this value in my nginx site config fixed the problem.

Upvotes: 4

Related Questions