这是本人参加的一个比较久远的项目的技术记载,如有错漏请指正
1、技术实现
1)在@ServerEndpoint
注解中指定 configurator = GetHttpSessionConfig.class。
@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfig.class)
2)创建配置类GetHttpSessionConfig,具体实现如下。
import jakarta.servlet.http.HttpSession;
import jakarta.websocket.HandshakeResponse;
import jakarta.websocket.server.HandshakeRequest;
import jakarta.websocket.server.ServerEndpointConfig;
import org.springframework.stereotype.Component;
@Component
public class GetHttpSessionConfig extends ServerEndpointConfig.Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
// 通过HandshakeRequest request获取httpSession,HandshakeRequest封装了HttpServletRequest
HttpSession httpSession = (HttpSession) request.getHttpSession();
sec.getUserProperties().put(HttpSession.class.getName(), httpSession);
}
}
HandshakeRequest
是HTTP请求的封装:在握手阶段,request
对象实际上是HTTP请求的封装,包含原始的HTTP请求头、参数、会话(如HttpSession
)等信息。因此,这里的request是跟websocket的链接请求关联的。这里的httpsession也是根据websocket的链接请求的头的Cookie中携带的JSESSIONID确定的。(使用postman测试时候,这个Cookie不会自动携带,需要手动添加)
3)在WebSocket端点中设置HttpSession属性,并且通过onOpen的EndpointConfig类型参数获取配置好的HttpSession进行装配。
private HttpSession httpSession;
@OnOpen
public void onOpen(Session session, EndpointConfig config) {
httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
}
通过以上实现,HttpSession就成功装配到WebSocket端点对象啦。
2、执行流程和参数传递机制
1)客户端通过ws://
或wss://
协议发起HTTP请求
ws://、
wss://链接请求本质是http请求
,当请求的路径匹配上使用Spring Boot的@EnableWebSocket
或@ServerEndpoint
注解设置的路径时,握手请求会绕过DispatcherServlet
,直接由WebSocket协议处理层(如Tomcat的WebSocket实现)接管,完成协议升级。
2)在WebSocket握手完成后,创建ServerEndpoint
实例之前,Spring会调用modifyHandshake
方法,允许开发者自定义握手逻辑。这里我们自定义了一个名为HttpSession.class.getName()返回值的一个属性,值是HttpSession对象。
3)创建ServerEndpoint后,若
WebSocket连接正式建立,会自动调用@OnOpen
注解标记的方法完成httpSession属性的装配。