使用jetty 11设置WebSocket

hec6srdp  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(549)

我正在尝试从jetty9.4迁移到jetty11(可能太早了?),但未能修改用于设置websockets的代码。我在9.4中实现这一点的方法如下:

Server server = new Server();
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.setSendServerVersion(false);
HttpConnectionFactory httpFactory = new HttpConnectionFactory(httpConfig);
ServerConnector httpConnector = new ServerConnector(server, httpFactory);
httpConnector.setPort(port);
server.setConnectors(new Connector[] { httpConnector });

// 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("/");

// Add a websocket to a specific path spec
ServletHolder holderEvents2 = new ServletHolder("websocket", EventsServlet.class);
context.addServlet(holderEvents2, "/events/*");

HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { context, new DefaultHandler() });

server.setHandler(handlers);

public class EventsServlet extends WebSocketServlet {

    @Override
    public void configure(WebSocketServletFactory factory) {
        // register a socket class as default
        factory.register(EchoSocket.class);
    }
}

public class EchoSocket implements WebSocketListener {
    // ...
}

因为不再有websocketservlet类了,所以我花了点时间找到了jettywebsocketservlet类。根据它的javadoc,我认为它应该如下所示:

public class EventsServlet extends JettyWebSocketServlet {

    @Override
    protected void configure(JettyWebSocketServletFactory factory) {
        // register a socket class as default
//      factory.register(EchoSocket.class);
           factory.addMapping("/", (req,res)->new EchoSocket());

    }
}

但是addmapping行实际上从未执行过。另外,jettywebsocketservletfactory没有一个名为setdefaultmaxframesize的方法,正如jettywebsocketservlet的javadoc所建议的那样。
我似乎能在网上找到的就是jetty<=9.4,甚至https://github.com/jetty-project/embedded-jetty-websocket-examples .
任何帮助都将不胜感激。

vnzz0bqm

vnzz0bqm1#

我有一个类似的问题,虽然我的版本下运行的Jetty9.4是有点不同,你的,使用 WebSocketHandler 而不是 WebSocketServlet . 我对旧的方法有一些问题,因为在jetty9.4下,我必须通过我的listener类 Class 对象,这使得依赖注入成为一种痛苦。
我现在已经在Jetty11.0.0下运行了。我发现你的问题,几天前,当我试图解决如何做到这一点在11号码头,它启发了我,实际上让这个工作,所以谢谢!
fwiw,我的jetty 9.4版本(用于一个简单的测试)如下所示:

public static void main(String[] argv) throws Exception
{
    int serverPort = Integer.getInteger("server.port", 8080);

    Server server = new Server(serverPort);
    ContextHandlerCollection handlers = new ContextHandlerCollection();

    WebSocketHandler wsh = new WebSocketHandler.Simple (TestWebSocketListener.class);
    handlers.addHandler(createContextHandler("/ws", wsh));

    ResourceHandler rh = new ResourceHandler();
    rh.setDirectoriesListed(false);
    rh.setBaseResource(Resource.newClassPathResource("/WEB-STATIC/"));
    handlers.addHandler(createContextHandler("/", rh));

    server.setHandler(handlers);

    server.start();
    server.join();
}

// Convenience method to create and configure a ContextHandler.
private static ContextHandler createContextHandler(String contextPath, Handler wrappedHandler)
{
    ContextHandler ch = new ContextHandler (contextPath);
    ch.setHandler(wrappedHandler);
    ch.clearAliasChecks();
    ch.setAllowNullPathInfo(true);
    return ch;
}

在这里, TestWebSocketListenerWebSocketListener 它只实现每个侦听器方法并将参数打印到 System.err . (我确实说过这是一个微不足道的测试。)我还在 onWebSocketText 回拨,只是为了确认这是否有效。
我没有用 DefaultHandler 这里-相反,我显式地创建 ResourceHandler 它从类路径中存储的资源树中提供一些简单的静态资源(在 /WEB-STATIC/ 前缀)。
我在jetty11.0.0下工作的版本只是改变了 main 上述方法:

public static void main(String[] argv) throws Exception
{
    int serverPort = Integer.getInteger("server.port", 8080);

    Server server = new Server(serverPort);
    ContextHandlerCollection handlers = new ContextHandlerCollection();

    ResourceHandler rh = new ResourceHandler();
    rh.setDirectoriesListed(false);
    rh.setBaseResource(Resource.newClassPathResource("/WEB-STATIC/"));
    handlers.addHandler(createContextHandler("/", rh));

    Servlet websocketServlet = new JettyWebSocketServlet() {
        @Override protected void configure(JettyWebSocketServletFactory factory) {
            factory.addMapping("/", (req, res) -> new TestWebSocketListener());
        }
    };
    ServletContextHandler servletContextHandler = new ServletContextHandler();
    servletContextHandler.addServlet(new ServletHolder(websocketServlet), "/ws");
    JettyWebSocketServletContainerInitializer.configure(servletContextHandler, null);
    handlers.addHandler(servletContextHandler);

    server.setHandler(handlers);

    server.start();
    server.join();
}

呼叫 JettyWebSocketServletContainerInitializer.configure 重要的是:没有这些,我就有异常抱怨websocket组件没有初始化。
需要注意的一点是,这两个处理程序的顺序已经更改—以前是 WebSocketHandler 是在 ResourceHandler . 但是,在使用 ServletContextHandler 对于本应由 ResourceHandler ,所以我交换了订单。
这个 TestWebSocketListener 两个版本之间是相同的。显然,现在我控制构造函数调用,添加依赖注入对我来说容易多了!
另一件事我不得不改变的是我拉进来的maven人工制品的名字。这个 websocket-server 神器似乎不再存在于11号码头,所以我改变了这个:

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-server</artifactId>
    <version>9.4.35.v20201120</version>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty.websocket</groupId>
    <artifactId>websocket-server</artifactId>
    <version>9.4.35.v20201120</version>
</dependency>

对此:

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-server</artifactId>
    <version>11.0.0</version>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty.websocket</groupId>
    <artifactId>websocket-jetty-server</artifactId>
    <version>11.0.0</version>
</dependency>
ecfdbz9o

ecfdbz9o2#

多亏了mdf的详细解释,我才得以修复代码。最后,我只需要更换

ServletHolder holderEvents = new ServletHolder("websocket", EventsServlet.class);
context.addServlet(holderEvents, "/events/*");

具有

Servlet websocketServlet = new JettyWebSocketServlet() {
    @Override
    protected void configure(JettyWebSocketServletFactory factory) {
        factory.addMapping("/", (req, res) -> new EchoSocket());
    }
};
context.addServlet(new ServletHolder(websocketServlet), "/events/*");
JettyWebSocketServletContainerInitializer.configure(context, null);

有了这个,我也可以摆脱eventsservlet类。

相关问题