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扫描下方二维码关注公众号和小程序↓↓↓