美文网首页
springboot使用websocket通讯携带httpses

springboot使用websocket通讯携带httpses

作者: 裸奔的刺猬 | 来源:发表于2021-10-29 16:29 被阅读0次

    PS:禁止拷贝形式转载,转载请以URL形式

    1.简介

    1. springboot+ websocket(WS协议基于HTTP协议)但 通讯时无法正常获取 其http 的session
    2. 基于参考版本进行附加优化

    2.参考

    https://www.cnblogs.com/coder163/p/8605645.html

    3.方案描述

    1. 基于参考改进版本,无需拦截器(参考版本实现拦截器的本质是提前创建好session)
    2. 直接再websocket 握手配置里面modifyHandshake() 进行创建sessoion

    4.代码实现

    4.1. 环境

    springboot:2.2.8RELEASE

    4.2. 代码

    config

    import lombok.extern.slf4j.Slf4j;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.subject.Subject;
    import org.apache.tomcat.websocket.server.WsHandshakeRequest;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.websocket.HandshakeResponse;
    import javax.websocket.server.HandshakeRequest;
    import javax.websocket.server.ServerEndpointConfig;
    import java.lang.reflect.Field;
    
    /**
     * @ClassName
     * @Description
     * @Author dyf
     * @Date 2021/10/29
     * @Version 1.0
     */
    @Slf4j
    @Component
    public class WebsocketConfig extends ServerEndpointConfig.Configurator {
        /* 修改握手,就是在握手协议建立之前修改其中携带的内容 */
        @Override
        public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
             //第一种方案
             //实现类为WsHandshakeRequest,该实现类保存了http request
            if (request instanceof WsHandshakeRequest) {
                try {
                    //反射获取HttpServletRequest 属性
                    Field field = request.getClass().getDeclaredField("request");
                    field.setAccessible(true);
                    HttpServletRequest httpServletRequest = (HttpServletRequest) field.get(request);
                    //如果不存在session 就创建session并且赋值给配置
                    sec.getUserProperties().put("session", httpServletRequest.getSession(true));
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    log.info("获取WS session失败", e);
                }
            }
    
          //第二种方案(基于Spring环境条件下)
           ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 
           sec.getUserProperties().put("session1", attributes.getRequest().getSession(true));
    
            super.modifyHandshake(sec, request, response);
        }
    
    }
    

    Websocket

    /**
     * @ClassName
     * @Description
     * @Author dyf
     * @Date 2021/10/29
     * @Version 1.0
     */
    @Slf4j
    @Component
    @ServerEndpoint(value = "/test", configurator = WebsocketConfig.class)
    public class Test{
    
        @OnOpen
        public void onOpen(Session session, EndpointConfig config) {
            HttpSession httpSession = (HttpSession) config.getUserProperties().get("session");
        }
    
    }
    

    相关文章

      网友评论

          本文标题:springboot使用websocket通讯携带httpses

          本文链接:https://www.haomeiwen.com/subject/yiwialtx.html