Jetty 9.1 has its own WebSocketUpgradeFilter
, use that one, and then modify the default policy's idle timeout.
Example:
package jetty.websocket;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter;
import org.eclipse.jetty.websocket.server.pathmap.ServletPathSpec;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
public class JettyWebSocketViaFilter
{
@WebSocket
public static class EchoSocket
{
@OnWebSocketMessage
public void onMessage(Session session, String msg)
{
session.getRemote().sendStringByFuture(msg);
}
}
public static class EchoCreator implements WebSocketCreator
{
private EchoSocket echoer = new EchoSocket();
@Override
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
{
return echoer;
}
}
public static void main(String[] args)
{
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(8080);
server.addConnector(connector);
// Setup the basic application "context" for this application at "/"
// This is also known as the handler tree (in jetty speak)
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
// Add the websocket filter
WebSocketUpgradeFilter wsfilter = WebSocketUpgradeFilter.configureContext(context);
wsfilter.getFactory().getPolicy().setIdleTimeout(5000);
wsfilter.addMapping(new ServletPathSpec("/"),new EchoCreator());
// The filesystem paths we will map
String staticRoot = "src/main/webapp/websocket/protocol";
ServletHolder holderDefault = new ServletHolder("default",DefaultServlet.class);
holderDefault.setInitParameter("resourceBase",staticRoot);
holderDefault.setInitParameter("dirAllowed","true");
context.addServlet(holderDefault,"/");
try
{
server.start();
server.join();
}
catch (Throwable t)
{
t.printStackTrace(System.err);
}
}
}
Timeouts in Jetty with WebSockets:
Since WebSocket is an upgraded HTTP/1.1 request you have essentially 2 timeouts to worry about.
First is the connector idle timeout, that will be used for the HTTP/1.1 initial portion of the incoming Upgrade request. This is configured at the server level, with the connector that it has. With Jetty, any value 0 or below is considered an infinite timeout.
Next, you have the websocket endpoint specific idle timeout. If it has a value greater than 0, then it is applied to already established connection's idle timeout (the one from the server side).
Some combinations and what it means ...
Server Connector IdleTimeout | WebSocket Endpoint IdleTimeout | Actual Timeout
------------------------------+--------------------------------+----------------
30,000 ms | -1 | 30,000 ms
30,000 ms | 10,000 ms | 10,000 ms
30,000 ms | 400,000 ms | 400,000 ms
500,000 ms | -1 | 500,000 ms
500,000 ms | 200 ms | 200 ms
-1 | -1 | (infinite)
-1 | 1,000 ms | 1,000 ms
You can think of the Server Connector IdleTimeout as a TCP level timeout, while the WebSocket endpoint timeout is an application level idle timeout.
Hope this helps.