Jetty 中的 JSR-356 javax websockets(嵌入式和非嵌入式)
JSR-356 javax websockets in Jetty (embedded and not)
鉴于:
我想将打包为 WAR 并包含 web.xml
的 webapp 部署到 Jetty 服务器。
在该应用程序中,我希望能够配置 JSR-356 指定的 javax websocket 端点。我更喜欢通过 ServerEndpointConfig
、 而不是 注释扫描来提供这些端点。
有许多资源举例说明了嵌入式 Jetty,利用著名的 WebSocketServerContainerInitializer.configureContext(context);
API。显然,我不能那样做。
还有其他的,直接跳转到ServletContextListener
,通过著名的context.getAttribute("javax.websocket.server.ServerContainer"
获得ServerContainer
。到目前为止,我通过这个 API 得到了很多 NULL
,所以显然没有添加容器。
问题:
缺少的配置是什么?最好通过 web.xml
来完成吗?如果它是关于 jetty.xml
或 jetty.ini
之类的配置文件 - 示例会很好,同样,最好是 xml
语法。
更新:
根据下面的答案(已接受的答案),正如我实际上试图在这里描述的那样 - 已知的配置方式 absolutely 工作得很好。说已知我的意思是通过将 --module=websocket
添加到非嵌入式 Jetty 的某些 *.ini
文件,或者通过调用 WebSocketServerContainerInitializer.configureContext
来获得嵌入式 Jetty。
所以重新表述这个问题:是否有人 experience/knowledge 通过纯粹基于 XML
的配置来启用 websocket 模块?
如果使用 ${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 服务器端点与您的 webapp 一起部署。
- 只需将 class 注释为
@ServerEndpoint
(来自 javax.websocket.server.ServerEndpoint
)
- 或者,如果您想以编程方式添加 WebSocket 服务器端点,您有 2 个选择。
- 在您的项目中提供
javax.websocket.server.ServerApplicationConfig
的实现,并 return 您希望 Jetty 部署的服务器端点。
- 在 WebApp startup/initialization 期间获取
javax.websocket.server.ServerContainer
from the ServletContext.getAttribute("javax.websocket.server.ServerContainer")
and use it's addEndpoint()
methods. Note that this is only possible from either a ServletContextListener.contextInitialized(ServletContextEvent sce)
or ServletContainerInitializer.onStartup(Set<Class<?>> c, ServletContext ctx)
为什么这在独立 Jetty 中有效?独立 Jetty 正在做什么来使这成为可能?
发生以下情况:
-
websocket
module 添加 lib/websocket/*.jar
到服务器 classpath
websocket
模块依赖于 client
和 annotations
模块
-
client
module 添加 lib/jetty-client-<jetty.version>.jar
到服务器 classpath
-
annotations
module 添加 lib/jetty-annotations-<jetty.version>.jar
和 lib/annotations/*.jar
到服务器 classpath
annotations
模块依赖于plus
模块
annotations
模块选择etc/jetty-annotations.xml
启动时执行
annotations
模块按名称添加JPMS模块org.objectweb.asm
-
plus
module 添加 lib/jetty-plus-<jetty.version>.jar
到服务器 classpath
plus
模块选择etc/jetty-plus.xml
启动时执行
plus
模块依赖于server
、security
、jndi
、webapp
和transactions
模块
(我将跳过以这种方式选择的其余模块)
简而言之,只需添加 websocket
模块,您就可以获得以下服务器 class 路径条目
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
行为可用于所有已部署的 WebApps。
您也可以 set the Configuration
on the WebAppContext
(在启动之前)针对 webapp 的特定行为。
示例:
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);
Note: for javax.websocket
you must use a WebAppContext
, as the behaviors defined for its initialization require a full Web App to function.
While you can use a ServletContextHandler
with javax.websocket
endpoints, this style is 100% manually defined, intialized, and declared, with no automatic bytecode / annotation scanning features that JSR-356 relies on.
您也可以从命令行看到所有这些。
显示活动的 ${jetty.base}
配置,XML 属性 值是什么,服务器 class 路径是什么,以及 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
鉴于:
我想将打包为 WAR 并包含 web.xml
的 webapp 部署到 Jetty 服务器。
在该应用程序中,我希望能够配置 JSR-356 指定的 javax websocket 端点。我更喜欢通过 ServerEndpointConfig
、 而不是 注释扫描来提供这些端点。
有许多资源举例说明了嵌入式 Jetty,利用著名的 WebSocketServerContainerInitializer.configureContext(context);
API。显然,我不能那样做。
还有其他的,直接跳转到ServletContextListener
,通过著名的context.getAttribute("javax.websocket.server.ServerContainer"
获得ServerContainer
。到目前为止,我通过这个 API 得到了很多 NULL
,所以显然没有添加容器。
问题:
缺少的配置是什么?最好通过 web.xml
来完成吗?如果它是关于 jetty.xml
或 jetty.ini
之类的配置文件 - 示例会很好,同样,最好是 xml
语法。
更新:
根据下面的答案(已接受的答案),正如我实际上试图在这里描述的那样 - 已知的配置方式 absolutely 工作得很好。说已知我的意思是通过将 --module=websocket
添加到非嵌入式 Jetty 的某些 *.ini
文件,或者通过调用 WebSocketServerContainerInitializer.configureContext
来获得嵌入式 Jetty。
所以重新表述这个问题:是否有人 experience/knowledge 通过纯粹基于 XML
的配置来启用 websocket 模块?
如果使用 ${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 服务器端点与您的 webapp 一起部署。
- 只需将 class 注释为
@ServerEndpoint
(来自javax.websocket.server.ServerEndpoint
) - 或者,如果您想以编程方式添加 WebSocket 服务器端点,您有 2 个选择。
- 在您的项目中提供
javax.websocket.server.ServerApplicationConfig
的实现,并 return 您希望 Jetty 部署的服务器端点。 - 在 WebApp startup/initialization 期间获取
javax.websocket.server.ServerContainer
from theServletContext.getAttribute("javax.websocket.server.ServerContainer")
and use it'saddEndpoint()
methods. Note that this is only possible from either aServletContextListener.contextInitialized(ServletContextEvent sce)
orServletContainerInitializer.onStartup(Set<Class<?>> c, ServletContext ctx)
- 在您的项目中提供
为什么这在独立 Jetty 中有效?独立 Jetty 正在做什么来使这成为可能?
发生以下情况:
-
websocket
module 添加lib/websocket/*.jar
到服务器 classpath websocket
模块依赖于client
和annotations
模块-
client
module 添加lib/jetty-client-<jetty.version>.jar
到服务器 classpath -
annotations
module 添加lib/jetty-annotations-<jetty.version>.jar
和lib/annotations/*.jar
到服务器 classpath annotations
模块依赖于plus
模块annotations
模块选择etc/jetty-annotations.xml
启动时执行annotations
模块按名称添加JPMS模块org.objectweb.asm
-
plus
module 添加lib/jetty-plus-<jetty.version>.jar
到服务器 classpath plus
模块选择etc/jetty-plus.xml
启动时执行plus
模块依赖于server
、security
、jndi
、webapp
和transactions
模块
(我将跳过以这种方式选择的其余模块)
简而言之,只需添加 websocket
模块,您就可以获得以下服务器 class 路径条目
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
行为可用于所有已部署的 WebApps。
您也可以 set the Configuration
on the WebAppContext
(在启动之前)针对 webapp 的特定行为。
示例:
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);
Note: for
javax.websocket
you must use aWebAppContext
, as the behaviors defined for its initialization require a full Web App to function. While you can use aServletContextHandler
withjavax.websocket
endpoints, this style is 100% manually defined, intialized, and declared, with no automatic bytecode / annotation scanning features that JSR-356 relies on.
您也可以从命令行看到所有这些。
显示活动的 ${jetty.base}
配置,XML 属性 值是什么,服务器 class 路径是什么,以及 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