繁体   English   中英

在 Spring/Stomp/Websocket/Messaging 中更改会话 ID

[英]Change session id in Spring/Stomp/Websocket/Messaging

我正在编写一个带有 spring 消息传递、stomp 和 rabbitmq 的应用程序。 我的应用程序已经将消息从浏览器发送到 rabbitmq 并返回。 但我不想要基于会话 id 的预定义 rabbitmq 队列名称。 我想在连接时更改会话 ID。 这是我试过的:

@Component
public class MyListener {

    private Logger logger = LoggerFactory.getLogger(getClass().getSimpleName());

    @EventListener
    public void x(SessionConnectEvent event) {
        Map<String, Object> headers = event.getMessage().getHeaders();
        String id = headers.get("simpSessionId").toString();
        logger.info("My current session id is " + id);
        headers.put("sessionId", "fred");
    }
}

错误是:地图是不可变的

您需要在客户端 <-> 服务器之间完成握手之前更新sessionId ,即定义 headers 属性时。

另一方面,侦听器SessionConnectEvent仅在握手完成后才执行。

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", "mySessiond");
    }
    return true;
}

public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
        Exception ex) {
}
}

也不要忘记在特定端点上注册拦截器

 @Override
 public void registerStompEndpoints(StompEndpointRegistry registry) {
  registry.addEndpoint("/greeting").addInterceptors(new HttpHandshakeInterceptor());
 }

更改会话 ID 不是正确的方法。 我使用 ServletFilter 进行 Cookie 和安全检查,并使用 @SendTo 正确使用 rabbitmq 队列。

您可以通过为每次握手创建一个 Principal 来更改会话 ID,然后您可以使用提供的用户名定位每个连接的会话:

class CustomHandshake extends DefaultHandshakeHandler {
    @Override
    public Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
        Principal principal = request.getPrincipal();
        if (principal == null) {
            principal = new AnonymousPrincipal();

            String uniqueName = UUID.randomUUID().toString();

            ((AnonymousPrincipal) principal).setName(uniqueName);
        }

        return principal;
    }

}

不要忘记注册处理程序如下:

.setHandshakeHandler(new CustomHandshake())

希望这是有帮助的

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM