Java CopyOnWriteArrayList为零而不是实际大小?

Java CopyOnWriteArrayList为零而不是实际大小?,java,spring-boot,Java,Spring Boot,可能是一些简单的事情,但我自己无法解决。我有一些SpringBootWebSockets实现的示例,希望显示总的活动会话。所以我创建了@ScheduledactiveSessions任务,它应该显示实际计数,但它总是0。调用afterConnectionEstablished时,我会得到预期的会话大小。有什么问题吗 @Configuration public class Monitoring extends TextWebSocketHandler { private List<

可能是一些简单的事情,但我自己无法解决。我有一些SpringBootWebSockets实现的示例,希望显示总的活动会话。所以我创建了
@Scheduled
activeSessions
任务,它应该显示实际计数,但它总是0。调用
afterConnectionEstablished
时,我会得到预期的会话大小。有什么问题吗

@Configuration
public class Monitoring extends TextWebSocketHandler {

    private List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message)
            throws Exception {

        String clientMessage = message.getPayload();
        System.out.println(clientMessage);
        sessions.forEach(s -> {
            try {
                s.sendMessage(new TextMessage("Hello! You session id is: " + s.getId()));
                activeSessions();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //the messages will be broadcasted to all users.
        System.out.println("Adding new session.");
        sessions.add(session);
        System.out.println("Current session count: " + sessions.size());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session);
    }

    @Scheduled(fixedRate = 2000)
    public void activeSessions() {
        System.out.println("Total sessions: " + sessions.size());
    }
}
到期日,自定义计划程序:

@Configuration
@EnableScheduling
public class SchedulingConfig {

    // https://stackoverflow.com/questions/49343692/websocketconfigurer-and-scheduled-are-not-work-well-in-an-application

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        taskScheduler.initialize();
        return taskScheduler;
    }
}

您当前有两个独立的
监控
类实例。一个由您自己创建,执行请求处理(它不是Spring管理的bean!),另一个由Spring检测到,原因是
@Configuration
(这不应该是
@Component
?)

删除
@Configuration
并将其替换为
@Bean
方法,这样您的
WebSocketConfig
如下所示

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(@NotNull WebSocketHandlerRegistry registry) {
        registry.addHandler(monitoring(), "/socket");
    }

    @Bean
    public Monitoring monitoring() {
        return new Monitoring();
    }
}

现在您有了一个bean实例,由Spring管理

请张贴你的全班。。。包括类标题等,以及如何配置此处理程序。我猜你有两个例子(您可以在消息中包含
hashcode
,或者您的消息中包含阻止正确创建代理的内容,从而导致从代理而不是嵌入式实例读取值。编辑了我的帖子。是的,确实,我尝试了ArrayList-完全相同。因此可能真的创建了两个实例。因此方向已经很好了。)寻找解决方案。我确定它有两个实例。删除
@Configuration
,并从
WebSocketConfig
中删除
新的监视器。将其替换为
@Bean
方法,该方法创建
监视
,这样您就有了一个实例。感谢您的想法。目前看起来是这样的:如果我是移动
@EnableWebSocket
,然后创建单个
监视
,但如果我尝试打开套接字,则会得到404。如果我再次添加
@EnableWebSocket
,则会创建两个实例(添加到监视构造函数的日志记录)。如何排除它的更多想法?您是否如我所述从
监控
类中删除了
@Configuration
。嗯,我的印象是,当在类路径上检测到web套接字时,web套接字将自动启用…显然我错了。另外,它可能看起来好像创建了2个实例,因为1个是代理。所以不要担心oled的日志。我想我会找到如何让它工作,谢谢!
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(@NotNull WebSocketHandlerRegistry registry) {
        registry.addHandler(monitoring(), "/socket");
    }

    @Bean
    public Monitoring monitoring() {
        return new Monitoring();
    }
}