springboot使用websocket通讯携带httpses
2021-10-29 本文已影响0人
裸奔的刺猬
PS:禁止拷贝形式转载,转载请以URL形式
1.简介
- springboot+ websocket(WS协议基于HTTP协议)但 通讯时无法正常获取 其http 的session
- 基于参考版本进行附加优化
2.参考
https://www.cnblogs.com/coder163/p/8605645.html
3.方案描述
- 基于参考改进版本,无需拦截器(参考版本实现拦截器的本质是提前创建好session)
- 直接再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");
}
}