Apache Wicket和嵌入式Jetty的Websocket超时

时间:2013-12-18 14:44:15

标签: websocket wicket embedded-jetty

我正在使用带有嵌入式Jetty网络服务器的Wicket。应用程序使用websockets,因此Jetty设置如下所示:

FilterHolder filterHolder = new FilterHolder(Jetty9WebSocketFilter.class);
filterHolder.setInitParameter("applicationClassName", "MyApplication");
filterHolder.setInitParameter("filterMappingUrlPattern", "/*");

WebAppContext context = new WebAppContext();
context.setResourceBase(".");
context.addFilter(filterHolder, "/*", null);
context.addServlet(DefaultServlet.class, "/*");

Server server = new Server(8083);
server.setHandler(context);

try {
    server.start();
} catch (Exception e) {
    e.printStackTrace();
}

除了websocket超时之外,一切正常。研究表明,Jetty的websocket连接超时,尽管这对于网络服务器来说并不常见。

经过研究,我偶然发现了以下init参数,现在我将传递给我的filterHolder

filterHolder.setInitParameter("maxIdleTime", "5000");

显然这个参数做了一些事情 - 因为现在超时发生的速度明显快于之前,恰好在5秒之后。

但我无法弄清楚如何完全禁用超时。使用-10甚至Integer.MIN_VALUE代替5000不会做任何事情,一段时间后仍会有超时。我发现的文档没有说明相应的值。

我可以使用什么init参数来禁用websocket超时?或者我是否必须坚持将超时设置为一些可笑的高值?

1 个答案:

答案 0 :(得分:2)

Jetty 9.1有自己的WebSocketUpgradeFilter,使用那个,然后修改默认策略的空闲超时。

示例:

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);
        }
    }
}

使用WebSockets在Jetty中超时:

由于WebSocket是升级的HTTP / 1.1请求,因此您基本上需要担心2次超时。

首先是连接器空闲超时,它将用于传入升级请求的HTTP / 1.1初始部分。这是在服务器级别配置的,具有它所具有的连接器。对于Jetty,任何0或以下的值都被视为无限超时。

接下来,您有websocket端点特定的空闲超时。如果它的值大于0,那么它将应用于已建立的连接的空闲超时(服务器端的那个)。

一些组合及其含义...

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

您可以将Server Connector IdleTimeout视为TCP级别超时,而WebSocket端点超时是应用程序级别的空闲超时。

希望这有帮助。