在发布这个问题之前,我在谷歌上搜索了很多关于这个问题的信息,从Web Socket@ServerEndpoint中的HttpServlet请求访问HttpSession是我能找到的最好的问题/答案之一,但它似乎不能解决我的问题。
我可以通过这种方式从websocket访问HttpSession,但我无法访问与正常HTTP请求相同的CDI会话bean实例。
我也尝试在会话中存储HttpSessionContextImpl
Weld实例,并尝试在WebSocket端使用它,但它没有公开以前的bean。
然后我的问题是:在这两种情况下(WebSocket事件和HTTP正常请求),是否可以访问相同的CDI管理的会话bean实例?
目前,让这个功能在Wildfly 9/10中运行对我来说很重要,但如果有一个通用的解决方案也能在Tomcat>7上运行(使用jBoss Weld或任何其他实现),那就太好了。
提前感谢您的支持。
那么我的问题是:在这两种情况下(WebSocket事件和HTTP正常请求),是否可以访问相同的CDI管理的会话bean实例
只有在握手请求期间,因为这是一个HTTP请求。HTTP会话仅在HTTP请求期间可用,而在WS请求期间不可用。希望原因现在已经很明显了,因为CDI将会话范围的bean存储在HTTP会话中,而HTTP会话只能通过HTTP请求来识别,并且在WS请求期间,任何地方都没有物理HTTP请求,因此HTTP会话也不可用。
最好的办法是生成一个唯一标识符,将其存储在会话范围的bean中,将其添加到WS-URL(作为路径或请求参数),在onOpen
期间提取它,并将其存储到应用程序范围的bean。在普通的JavaEE服务器中,应用程序范围的CDI-beans可以通过通常的方式在WS端点类中的@Inject
获得(但在Tomcat/JJetty/等中则不然,您必须通过BeanManager
手动获取它)。最后,只需让包含唯一标识符的会话范围的bean咨询应用程序范围的bean,以查找该标识符打开的任何套接字。
至少,我在为JSF开发OmniFaces<o:socket>
标签时走上了这条路。它都是开源的,你可以在它的展示页面底部找到源代码链接。