在服务器应用程序中,我使用没有弹簧消息传递层和sockjs/stomp的裸Websockets。我需要在上面有自己的消息传递层,但我想使用例如 spring 会话来利用 servlet HttpSession 替换来保持 websocket 会话下方的 http 会话处于活动状态,以防止超时。websocket 是使用 JavaScript 从静态 HTML 页面打开的。
在 spring-framework 文档中,有设置裸 websocket 支持的所有必要信息,例如基本的 BinaryWebSocketHandler 或 TextWebSocketHandler 以及如何提供您自己的握手拦截器。
我添加了带有 hazelcast 的春季会话 1.1.0.RC1,用于存储会话并将 servlet 容器 HttpSession 实现替换为春季会话提供的会话/过期会话。我只是按照给定的说明进行操作。
到目前为止一切都很好,但是由于我提供了一个静态的HTML页面,我使用JavaScript从中打开websocket,而不使用spring安全性或任何其他机制来触发servlet容器的处理,到目前为止还没有初始化http会话。
所以问题是:我如何启动自定义 HttpSession 然后存储在 Spring 会话提供的 SessionRepository 中?
注意:我会自己提供一个答案,因为我认为我为我的案例解决了问题,这对面临类似问题的其他人可能会有所帮助。
从 spring-framework 文档中可以看出,可以添加一个自定义的 HandshakeInterceptor。春季会议提供
// example for reference:
org.springframework.session.web.socket.server.SessionRepositoryMessageInterceptor
它针对 Spring 消息传递层。它展示了如何在方法preSend(...)中发送消息之前重置HttpSession的计时器,以及如何在Handshake(...)方法中选择请求的HttpSession。
我基于此实现了我自己的握手拦截器,使用几乎相同的先前握手(...)方法,但有一个微小的区别,当然省略了ChannelInterceptorAdapter的东西。HttpSession 时间的重置必须在其他地方完成,但这超出了范围。
因为在我的情况下到目前为止还没有创建 HttpSession,所以我将从请求中获取会话的行更改为如下所示:
HttpSession session = servletRequest.getServletRequest().getSession(true);
在方法 getSession(...) 中将布尔参数从 false 更改为 true。现在,如果到目前为止没有可用的HttpSession,则此调用将触发创建新的HttpSession(由Spring session提供)。
这个解决方案似乎可以满足我的情况。如果我遗漏了某些内容或以错误的方式使用任何东西,请纠正我。