如何将CDI会话bean从HTTP会话传播到WebSocket会话? [英] How to propagate CDI session beans from HTTP session to WebSocket session?

查看:196
本文介绍了如何将CDI会话bean从HTTP会话传播到WebSocket会话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在发布此问题之前搜索了很多这个问题并且从Web套接字@ServerEndpoint中访问HttpServletRequest中的HttpSession 是我能找到的最好的问题/答案之一,但它似乎无法解决我的问题。

I googled a lot for this problem before posting this question and Accessing HttpSession from HttpServletRequest in a Web Socket @ServerEndpoint is one of the best Questions/Answers I was able to found, but it appears to not solve my problem.

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

I was able to access HttpSession from websocket in this way, but I can't access the same CDI session bean instances as from normal HTTP requests.

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

I tried to store in session the HttpSessionContextImpl Weld instance too and tried to use it on WebSocket side, but it didn't expose previous beans.

然后我的问题:在两种情况下都可以访问相同的CDI托管会话bean实例(WebSocket事件和HTTP正常请求)吗?

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

对于我来说,让这个功能在Wildfly 9/10中运行很重要,但它如果有一个通用的解决方案,例如Tomcat> 7(使用jBoss Weld或任何其他实现)也很棒。

At the moment it is important for me to have this feature working in Wildfly 9/10, but it would be great to have a general solution working for example on Tomcat > 7 too (using jBoss Weld or any other implementation).

提前感谢您的支持。

推荐答案


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

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

Only during the handshake request, because that's a HTTP request. The HTTP session is only available during a HTTP request, not during a WS request. Hopefully the reason is by now obvious as CDI stores session scoped beans in HTTP session which is only identifiable by a HTTP request, and during a WS request there's no means of a physical HTTP request anywhere and therefore HTTP session is also unavailable.

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

Your best bet is generating an unique identifier, store it in a session scoped bean, add it to the WS URL (as either path or request parameter), extract it during onOpen and store it in an application scoped bean. In normal Java EE servers, application scoped CDI beans are available via @Inject in a WS endpoint class the usual way (but not in Tomcat/Jetty/etc, you'd have to manually grab it via BeanManager). Finally, just let the session scoped bean containing the unique identifier consult the application scoped bean for any opened sockets by that identifier.

至少,我在开发时使用了这条路径适用于JSF的OmniFaces < o:socket> 标记。它是全部开源的,您可以在其展示页面的底部找到源代码链接。

At least, I went this path while developing the OmniFaces <o:socket> tag for JSF. It's all open source, you can find source code links at the bottom of its showcase page.

这篇关于如何将CDI会话bean从HTTP会话传播到WebSocket会话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆