如何在 Spring WebSocketStompClient 中获取会话 ID?
How to get Session Id in Spring WebSocketStompClient?
如何在 Java Spring WebSocketStompClient 中获取会话 ID?
我有 WebSocketStompClient 和 StompSessionHandlerAdapter,它们可以很好地连接到我服务器上的 websocket。 WebSocketStompClient 使用 SockJsClient。
但我不知道如何获取 websocket 连接的会话 ID。在客户端带有 stomp 会话处理程序的代码中
private class ProducerStompSessionHandler extends StompSessionHandlerAdapter {
...
@Override
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
...
}
stomp session 包含session id,与服务器上的session id不同。
所以从这个 ids:
DEBUG ... Processing SockJS open frame in WebSocketClientSockJsSession[id='d6aaeacf90b84278b358528e7d96454a...
DEBUG ... DefaultStompSession - Connection established in session id=42e95c88-cbc9-642d-2ff9-e5c98fb85754
我需要来自 WebSocketClientSockJsSession 的第一个会话 ID。
但是我没有在 WebSocketStompClient 或 SockJsClient 中找到任何方法来检索诸如会话 ID 之类的东西...
要获取会话 ID,您需要如下定义自己的拦截器并将会话 ID 设置为自定义属性。
public class HttpHandshakeInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession();
attributes.put("sessionId", session.getId());
}
return true;
}
现在您可以在控制器中获取相同的会话 ID class。
@MessageMapping("/message")
public void processMessageFromClient(@Payload String message, SimpMessageHeaderAccessor headerAccessor) throws Exception {
String sessionId = headerAccessor.getSessionAttributes().get("sessionId").toString();
}
您可以使用@Header
注解访问sessionId:
@MessageMapping("/login")
public void login(@Header("simpSessionId") String sessionId) {
System.out.println(sessionId);
}
而且它在没有任何自定义拦截器的情况下对我来说工作正常
有一种方法可以通过反射提取 sockjs sessionId API:
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
// we need another sessionId!
System.out.println("New session established : " + session.getSessionId());
DefaultStompSession defaultStompSession =
(DefaultStompSession) session;
Field fieldConnection = ReflectionUtils.findField(DefaultStompSession.class, "connection");
fieldConnection.setAccessible(true);
String sockjsSessionId = "";
try {
TcpConnection<byte[]> connection = (TcpConnection<byte[]>) fieldConnection.get(defaultStompSession);
try {
Class adapter = Class.forName("org.springframework.web.socket.messaging.WebSocketStompClient$WebSocketTcpConnectionHandlerAdapter");
Field fieldSession = ReflectionUtils.findField(adapter, "session");
fieldSession.setAccessible(true);
WebSocketClientSockJsSession sockjsSession = (WebSocketClientSockJsSession) fieldSession.get(connection);
sockjsSessionId = sockjsSession.getId(); // gotcha!
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (StringUtils.isBlank(sockjsSessionId)) {
throw new IllegalStateException("couldn't extract sock.js session id");
}
String subscribeLink = "/topic/auth-user" + sockjsSessionId;
session.subscribe(subscribeLink, this);
System.out.println("Subscribed to " + subscribeLink);
String sendLink = "/app/user";
session.send(sendLink, getSampleMessage());
System.out.println("Message sent to websocket server");
}
可以在这里看到:tutorial
如何在 Java Spring WebSocketStompClient 中获取会话 ID?
我有 WebSocketStompClient 和 StompSessionHandlerAdapter,它们可以很好地连接到我服务器上的 websocket。 WebSocketStompClient 使用 SockJsClient。
但我不知道如何获取 websocket 连接的会话 ID。在客户端带有 stomp 会话处理程序的代码中
private class ProducerStompSessionHandler extends StompSessionHandlerAdapter {
...
@Override
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
...
}
stomp session 包含session id,与服务器上的session id不同。 所以从这个 ids:
DEBUG ... Processing SockJS open frame in WebSocketClientSockJsSession[id='d6aaeacf90b84278b358528e7d96454a...
DEBUG ... DefaultStompSession - Connection established in session id=42e95c88-cbc9-642d-2ff9-e5c98fb85754
我需要来自 WebSocketClientSockJsSession 的第一个会话 ID。 但是我没有在 WebSocketStompClient 或 SockJsClient 中找到任何方法来检索诸如会话 ID 之类的东西...
要获取会话 ID,您需要如下定义自己的拦截器并将会话 ID 设置为自定义属性。
public class HttpHandshakeInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession();
attributes.put("sessionId", session.getId());
}
return true;
}
现在您可以在控制器中获取相同的会话 ID class。
@MessageMapping("/message")
public void processMessageFromClient(@Payload String message, SimpMessageHeaderAccessor headerAccessor) throws Exception {
String sessionId = headerAccessor.getSessionAttributes().get("sessionId").toString();
}
您可以使用@Header
注解访问sessionId:
@MessageMapping("/login")
public void login(@Header("simpSessionId") String sessionId) {
System.out.println(sessionId);
}
而且它在没有任何自定义拦截器的情况下对我来说工作正常
有一种方法可以通过反射提取 sockjs sessionId API:
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
// we need another sessionId!
System.out.println("New session established : " + session.getSessionId());
DefaultStompSession defaultStompSession =
(DefaultStompSession) session;
Field fieldConnection = ReflectionUtils.findField(DefaultStompSession.class, "connection");
fieldConnection.setAccessible(true);
String sockjsSessionId = "";
try {
TcpConnection<byte[]> connection = (TcpConnection<byte[]>) fieldConnection.get(defaultStompSession);
try {
Class adapter = Class.forName("org.springframework.web.socket.messaging.WebSocketStompClient$WebSocketTcpConnectionHandlerAdapter");
Field fieldSession = ReflectionUtils.findField(adapter, "session");
fieldSession.setAccessible(true);
WebSocketClientSockJsSession sockjsSession = (WebSocketClientSockJsSession) fieldSession.get(connection);
sockjsSessionId = sockjsSession.getId(); // gotcha!
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (StringUtils.isBlank(sockjsSessionId)) {
throw new IllegalStateException("couldn't extract sock.js session id");
}
String subscribeLink = "/topic/auth-user" + sockjsSessionId;
session.subscribe(subscribeLink, this);
System.out.println("Subscribed to " + subscribeLink);
String sendLink = "/app/user";
session.send(sendLink, getSampleMessage());
System.out.println("Message sent to websocket server");
}
可以在这里看到:tutorial