【问题标题】:JSR-356 javax websockets in Jetty (embedded and not)Jetty 中的 JSR-356 javax websockets(嵌入式和非嵌入式)
【发布时间】:2018-11-28 06:09:05
【问题描述】:

鉴于:

我想将 webapp(打包为 WAR,其中包含 web.xml)部署到 Jetty 服务器。

在该应用程序中,我希望能够配置 JSR-356 指定的 javax websocket 端点。我更喜欢那些通过ServerEndpointConfig 提供的端点,不是注释扫描。

有许多资源可以通过嵌入式 Jetty 来举例说明,这些资源利用了众所周知的 WebSocketServerContainerInitializer.configureContext(context); API。很明显,我做不到。

还有其他的,直接跳转到ServletContextListener,通过著名的context.getAttribute("javax.websocket.server.ServerContainer"获得ServerContainer)。到目前为止,我通过这个 API 得到了很多 NULL,所以显然没有添加容器。

问题:

缺少的配置是什么?可以通过web.xml 完成吗?如果它是关于像 jetty.xmljetty.ini 这样的配置文件 - 再一次的例子会很好,最好是 xml 语法。

更新:

根据下面的答案(已接受的答案)以及我实际上试图在这里描述的那样 - 已知的配置方式绝对工作得很好。说已知我的意思是通过将--module=websocket 添加到某个非嵌入式码头的*.ini 文件,或者通过调用WebSocketServerContainerInitializer.configureContext 来获取嵌入式码头。

所以换个说法:有人有任何经验/知识可以通过纯粹基于XML 的配置来启用 websocket 模块吗?

【问题讨论】:

    标签: java xml websocket jetty jsr356


    【解决方案1】:

    如果使用${jetty.base}${jetty.home} recommended installation process for Standalone Jetty,您应该转到您的${jetty.base} 实例目录并启用websocket 模块。

    $ cd /path/to/mybase
    $ java -jar /opt/jetty/jetty-home-9.4.14.v20181114/start.jar --add-to-start=websocket
    $ grep "websocket" start.ini
    --module=websocket
    

    现在您已经为 ${jetty.base} 实例启用了 websocket。

    如果您希望 Jetty 通过字节码扫描您部署的 web 应用以查找注释来发现您的服务器 WebSocket 端点,那么您还需要 annotations 模块。

    $ cd /path/to/mybase
    $ java -jar /opt/jetty/jetty-home-9.4.14.v20181114/start.jar --add-to-start=annotations
    $ grep "annotations" start.ini
    --module=annotations
    

    完成后,您可以执行以下一项(或多项)操作以将 websocket 服务器端点与您的 web 应用程序一起部署。

    为什么这在独立的 Jetty 中有效?独立的 Jetty 做了什么来使这成为可能?

    会发生以下情况:

    • websocket modulelib/websocket/*.jar 添加到服务器类路径
    • websocket 模块依赖于 clientannotations 模块
    • client modulelib/jetty-client-<jetty.version>.jar 添加到服务器类路径
    • annotations modulelib/jetty-annotations-<jetty.version>.jarlib/annotations/*.jar 添加到服务器类路径中
    • annotations 模块依赖于plus 模块
    • annotations 模块选择 etc/jetty-annotations.xml 在启动时执行
    • annotations 模块按名称添加 JPMS 模块org.objectweb.asm
    • plus modulelib/jetty-plus-<jetty.version>.jar 添加到服务器类路径
    • plus 模块选择 etc/jetty-plus.xml 在启动时执行
    • plus 模块依赖于 serversecurityjndiwebapptransactions 模块

    (我将跳过以这种方式选择的其余模块)

    简而言之,只需添加 websocket 模块,您就可以获得以下服务器类路径条目

    lib/websocket/*.jar
    lib/jetty-client-<jetty.version>.jar
    lib/jetty-annotations-<jetty.version>.jar
    lib/annotations/*.jar
    lib/jetty-plus-<jetty.version>.jar
    

    以及以下 XML 文件

    lib/jetty-annotations.xml
    lib/jetty-plus.xml
    

    这两个 XML 文件都只是修改了服务器端的默认 Configuration 列表,使它们引入的 Configuration 行为可用于所有已部署的 WebApp。

    您也可以set the Configuration on the WebAppContext(在它开始之前)针对 web 应用的特定行为。

    例子:

    WebAppContext context = new WebAppContext();
    context.setContextPath("/");
    context.setBaseResource(Resource.newResource(rootResourceUrl));
    
    context.setConfigurations(new Configuration[] {
                new AnnotationConfiguration(),
                new WebXmlConfiguration(),
                new WebInfConfiguration(),
                new PlusConfiguration(), 
                new MetaInfConfiguration(),
                new FragmentConfiguration(), 
                new EnvConfiguration()});    
    
    handlerList.addHandler(context);
    

    注意:对于javax.websocket,您必须使用WebAppContext,因为为其初始化定义的行为需要完整的Web 应用程序才能运行。 虽然您可以将 ServletContextHandlerjavax.websocket 端点一起使用,但这种样式是 100% 手动定义、初始化和声明的,没有 JSR-356 依赖的自动字节码/注释扫描功能。

    您也可以从命令行查看所有这些内容。

    显示活动的${jetty.base} 配置,XML 属性值是什么,服务器类路径是什么,以及将执行什么 XML(以及以什么顺序!!)

    $ cd /path/to/mybase
    $ java -jar /opt/jetty/jetty-home-9.4.14.v20181114/start.jar --list-config
    

    显示模块列表以及它们之间的关系(以及在您的${jetty.base} 配置中选择的模块)

    $ cd /path/to/mybase
    $ java -jar /opt/jetty/jetty-home-9.4.14.v20181114/start.jar --list-modules
    

    【讨论】:

    • 正如我在问题中所述,您在此处概述的路径对我来说是已知的并且正在工作--module=websocketWebSocketServerContainerInitializer.configureContext(context) 的一些味道。太糟糕了我的情况更困难:在历史上,我部署了 embedded Jetty 从 Java 配置为读取 XML 文件并由它们配置。对此有什么建议吗?
    • “模块”是 Jetty 9.x 中一个纯粹独立的 Jetty 概念。 Jetty 10.x 中引入了嵌入式码头的“模块”,但作为正式的 JPMS 模块。
    • 感谢您对看似不可能的事情的认可(Jetty 9.4..)。好吧,看起来我要放弃 JAVAX 方式并使用 WebSockets 'Jetty' 方式(servlet 等)。
    • 如果您愿意,您仍然可以执行inferior javax way,您只需在为您的 JSR-356 (javax.websocket) 行为启动 WebAppContext 之前声明服务器 Configuration。注意:您必须使用WebAppContext,而不是ServletContextHandler
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多