Java WebSocket 获取 HttpSession
Java WebSocket Session About 2,696 words原理
WebSocket在建立时握手阶段是建立在HTTP协议之上,握手成功升级为TCP长链接。在握手阶段获取HttpSession,设置到WebSocket的Session中即可。
前提
HTTP服务端口必须和WebSocket端口为同一个(比如:8080),不能一个使用代理端口,一个直接使用服务端口。
代码
配置类:从握手阶段获取到HttpSession,如果不为null,则放入WebSocketSession中的用户配置Map中。
public class WebSocketServerConfigurator extends ServerEndpointConfig.Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
HttpSession httpSession = (HttpSession) request.getHttpSession();
if (httpSession != null) {
Map<String, Object> userProperties = sec.getUserProperties();
userProperties.put(HttpSession.class.getName(), httpSession);
}
}
}
设置自定义的Configurator:
@ServerEndpoint(value = "/test/ws/{username}", configurator = WebSocketServerConfigurator.class)
public class WebSocketServer {
@OnOpen
public void onOpen(@PathParam("username") String username, Session session) {
HttpSession httpSession = (HttpSession) session.getUserProperties().get(HttpSession.class.getName());
System.out.println("onOpen#" + httpSession);
// 最大超时时间 60 秒
session.setMaxIdleTimeout(TimeUnit.MINUTES.toMillis(5));
session.setMaxBinaryMessageBufferSize(8192 * 1024); // 8KB
session.setMaxTextMessageBufferSize(8192 * 1024); // 字符数
session.getAsyncRemote().sendText("123");
}
// ... 省略了其他事件
}
注意
如果一开始没有请求没有初始化HttpSession(如刚进入网页就连接WebSocket),则WebSocket握手阶段HandshakeRequest获取到的HttpSession为null,此时再在别的Servlet中设置HttpSession,WebSocket中始终获取不到HttpSession。
解决办法
方法一
连接WebSocket操作放在初始化了HttpSession之后。比如登录后写入相关信息到HttpSession。
方法二
增加ServertRequestListener,在每次请求初始化时都去获取一次HttpSession(如果请求没有关联的HttpSession,则创建一个新的),这样此次用户浏览网页时都是关联的同一个Session。
@WebListener
public class MyServletListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
HttpSession session = request.getSession();
System.out.println("requestInitialized session = " + session);
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("requestDestroyed sre = " + sre);
}
}
可以看到getSession表示:返回请求关联的 session, 若请求没有 session 则创建一个。
public interface HttpServletRequest extends ServletRequest {
/**
* Returns the current session associated with this request, or if the
* request does not have a session, creates one.
*
* @return the <code>HttpSession</code> associated with this request
* @see #getSession(boolean)
*/
public HttpSession getSession();
}
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓