springboot使用websocket通讯携带httpses

2021-10-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");
    }

}
上一篇下一篇

猜你喜欢

热点阅读