You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取STOMP已连接会话列表?Spring代码获取失败问题

问题原因

SimpUserRegistry.getUserCount()统计的是经过认证关联的用户会话数,你用Chrome APIC扩展连接时,没有在STOMP连接过程中提供用户身份信息,Spring无法将该WebSocket会话关联到任何SimpUser对象,所以返回0。

注意:日志里的WebSocketSession[2 current WS(2)]是底层的WebSocket连接数,和SimpUserRegistry的统计维度完全不同——前者只要建立了WebSocket连接就算,后者必须是关联了认证用户的会话才会被统计。

解决方案

方案1:通过自定义拦截器关联用户标识(无需完整认证)

如果不需要严格的用户认证,只是想让SimpUserRegistry统计所有连接,可以自定义握手拦截器,在握手时为每个连接设置一个匿名用户标识:

1.1 实现HandshakeInterceptor

@Component
public class StompUserHandshakeInterceptor implements HandshakeInterceptor {
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        // 示例从URL参数获取用户标识,也可从请求头、Cookie等地方取
        ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
        String username = servletRequest.getServletRequest().getParameter("username");
        // 未传username则生成唯一匿名标识
        if (username == null) {
            username = "anonymous-" + UUID.randomUUID();
        }
        // 创建匿名认证对象绑定到会话属性
        Authentication auth = new UsernamePasswordAuthenticationToken(username, null, Collections.emptyList());
        attributes.put("user", auth);
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
        // 无需处理
    }
}

1.2 注册拦截器到WebSocket配置

修改你的WebSocketConfiguration,添加拦截器:

@EnableWebSocketMessageBroker
@Configuration
@RequiredArgsConstructor
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {

    private final StompUserHandshakeInterceptor handshakeInterceptor;

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/my-chat")
                .setAllowedOriginPatterns("*")
                .addInterceptors(handshakeInterceptor); // 注册自定义拦截器
    }
    
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/pub");
        registry.enableSimpleBroker("/sub");
    }
}

1.3 客户端连接时携带标识(可选)

用APIC扩展连接时,可在URL后拼接参数:ws://localhost:8080/my-chat?username=test-user,拦截器会使用指定用户名;若不拼接,会自动生成匿名用户名。此时SimpUserRegistry.getUserCount()就能正确统计连接数。

方案2:直接统计底层WebSocket连接数

如果只是想获取所有已建立的STOMP连接数(不管是否认证),可以直接注入WebSocketMessageBrokerStats来获取:

@Autowired
private WebSocketMessageBrokerStats webSocketMessageBrokerStats;

@Scheduled(fixedRate = 1000)
public void getConnectedUserSessions() {
    // 获取当前活跃的WebSocket会话数,和日志里的WS数值一致
    int currentSessions = webSocketMessageBrokerStats.getWebSocketSessionStats().getCurrentSessionCount();
    System.out.println("当前活跃STOMP连接数:" + currentSessions);
}

方案3:使用Spring Security完成用户认证

如果系统需要严格的用户认证,可以配置Spring Security,让客户端在连接时携带认证信息(比如JWT令牌、Basic Auth)。Spring会自动将认证通过的用户关联到SimpUserRegistry,此时getUserCount()会返回已认证用户的会话数。


内容的提问来源于stack exchange,提问作者Viper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:33:08