如何将 CDI 会话 bean 从 HTTP 会话传播到 WebSocket 会话?

How to propagate CDI session beans from HTTP session to WebSocket session?

在发布这个问题之前,我在谷歌上搜索了很多, 是我能找到的最好的 Questions/Answers 之一,但它似乎没有解决我的问题。

我能够以这种方式从 websocket 访问 HttpSession,但我无法访问与普通 HTTP 请求相同的 CDI 会话 bean 实例。

我也尝试在会话中存储 HttpSessionContextImpl Weld 实例并尝试在 WebSocket 端使用它,但它没有公开以前的 bean。

那么我的问题是:是否可以在两种情况下(WebSocket 事件和 HTTP 正常请求)访问相同的 CDI 管理的会话 bean 实例?

目前让这个功能在 Wildfly 9/10 中工作对我来说很重要,但是如果有一个通用的解决方案也能在 Tomcat > 7 上工作(使用 jBoss 焊接或任何其他实现)。

在此先感谢您的支持。

Then my question: Is it possible to access the same CDI managed session bean instances in both cases (WebSocket events and HTTP normal requests)?

仅在握手请求期间,因为那是一个 HTTP 请求。 HTTP 会话仅在 HTTP 请求期间可用,在 WS 请求期间不可用。希望原因现在很明显,因为 CDI 在 HTTP 会话中存储会话范围的 bean,只能通过 HTTP 请求识别,而在 WS 请求期间,任何地方都无法进行物理 HTTP 请求,因此 HTTP 会话也不可用。

您最好的选择是生成一个唯一标识符,将其存储在会话范围的 bean 中,将其添加到 WS URL(作为路径或请求参数),在 onOpen 期间提取它,然后将其存储在应用程序范围的 bean 中。在普通的 Java EE 服务器中,应用程序范围的 CDI bean 可以通过 @Inject 在 WS 端点 class 中以通常的方式使用(但在 Tomcat/Jetty/etc 中则不行,您必须手动通过 BeanManager 获取它)。最后,让包含唯一标识符的会话作用域 bean 查询应用程序作用域 bean,以了解该标识符打开的任何套接字。

至少,我在为 JSF 开发 OmniFaces <o:socket> 标签时选择了这条路。全部开源,源码链接在its showcase page.

底部