PS:禁止拷貝形式轉(zhuǎn)載,轉(zhuǎn)載請以URL形式
1.簡介
- springboot+ websocket(WS協(xié)議基于HTTP協(xié)議)但 通訊時無法正常獲取 其http 的session
- 基于參考版本進(jìn)行附加優(yōu)化
2.參考
https://www.cnblogs.com/coder163/p/8605645.html
3.方案描述
- 基于參考改進(jìn)版本,無需攔截器(參考版本實(shí)現(xiàn)攔截器的本質(zhì)是提前創(chuàng)建好session)
- 直接再websocket 握手配置里面
modifyHandshake()進(jìn)行創(chuàng)建sessoion
4.代碼實(shí)現(xiàn)
4.1. 環(huán)境
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 {
/* 修改握手,就是在握手協(xié)議建立之前修改其中攜帶的內(nèi)容 */
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
//第一種方案
//實(shí)現(xiàn)類為WsHandshakeRequest,該實(shí)現(xiàn)類保存了http request
if (request instanceof WsHandshakeRequest) {
try {
//反射獲取HttpServletRequest 屬性
Field field = request.getClass().getDeclaredField("request");
field.setAccessible(true);
HttpServletRequest httpServletRequest = (HttpServletRequest) field.get(request);
//如果不存在session 就創(chuàng)建session并且賦值給配置
sec.getUserProperties().put("session", httpServletRequest.getSession(true));
} catch (NoSuchFieldException | IllegalAccessException e) {
log.info("獲取WS session失敗", e);
}
}
//第二種方案(基于Spring環(huán)境條件下)
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");
}
}