spring中怎么利用websocket获取HttpSession-成都快上网建站

spring中怎么利用websocket获取HttpSession

这期内容当中小编将会给大家带来有关 spring中怎么利用websocket获取HttpSession,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

旅顺口网站建设公司成都创新互联公司,旅顺口网站设计制作,有大型网站制作公司丰富经验。已为旅顺口上千提供企业网站建设服务。企业网站搭建\外贸网站制作要多少钱,请找那个售后服务好的旅顺口做网站的公司定做!


一个普通网站,用户登录后,将用户信息存在HttpSession中。现在网站需要加入即时聊天功能,打算使用Websocket实现,需要在Websocket中拿到HttpSession来表示用户。

    /**
     * 交流
     * @param chatMessage
     */
    @MessageMapping("/chat")
    public void chat(HttpSession session, @RequestBody ChatMessage chatMessage) {
        User user = (User)session.get("user");    // error
        chatService.chat(user,chatMessage);
    }

普通的注入HttpSession是不行的,因为Websocket连接建立后,并不会HTTP协议那样,每次传输数据都会带上sessionid。

解决思路
在Websocket连接建立阶段(此时还是HTTP协议)拦截HTTP请求,获取到HttpSesion并保存。

实现
本来想自己写个类,但发现Spring Websocket已经提供了这样的拦截器HttpSessionHandshakeInterceptor,直接使用即可。

Websocket 代理配置
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/chat");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/endpoint").setAllowedOrigins("*").addInterceptors(new HttpSessionHandshakeInterceptor()).withSockJS();
    }
}

这里和普通的Websocket配置差不多,最大的区别是addInterceptors(new HttpSessionHandshakeInterceptor()),它把HttpSessionHandshakeInterceptor加入到了拦截链中。
我们可以看一下HttpSessionHandshakeInterceptor源码中的相关方法

// 在握手完成前(连接建立阶段)
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception {
        HttpSession session = this.getSession(request);     
        if (session != null) {
            if (this.isCopyHttpSessionId()) {
                attributes.put("HTTP.SESSION.ID", session.getId());  // 保存 sessionid
            }

            Enumeration names = session.getAttributeNames();

            while(true) {
                String name;
                do {
                    if (!names.hasMoreElements()) {
                        return true;
                    }

                    name = (String)names.nextElement();
                } while(!this.isCopyAllAttributes() && !this.getAttributeNames().contains(name));

                attributes.put(name, session.getAttribute(name));    // 保存HttpSession中的信息
            }
        } else {
            return true;
        }
}

// 获取HttpSession
private HttpSession getSession(ServerHttpRequest request) {
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest serverRequest = (ServletServerHttpRequest)request;
            return serverRequest.getServletRequest().getSession(this.isCreateSession());
        } else {
            return null;
        }
}


通过源码我们可以知道,HttpSessionHandshakeInterceptor将HttpSession中的值保存到了一个Map里面,通过搜索spring的官方文档,我发现可以通过注入SimpMessageHeaderAccessor在Controller方法中获取到那些值。

    /**
     * 交流
     * @param chatMessage
     */
    @MessageMapping("/chat")
    public void chat(SimpMessageHeaderAccessor headerAccessor, @RequestBody ChatMessage chatMessage) {
        User user = (User) headerAccessor.getSessionAttributes().get("user");  // right
        chatService.chat(user,chatMessage);
    }

上述就是小编为大家分享的 spring中怎么利用websocket获取HttpSession了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联行业资讯频道。


本文题目:spring中怎么利用websocket获取HttpSession
本文路径:http://kswjz.com/article/iepojp.html
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流