CopyOnWriteArrayList是零而不是实际大小?

时间:2018-06-14 09:54:23

标签: java spring-boot

可能是一件简单的事情,但我无法自己解决这个问题。我有一些Spring Boot WebSockets实现的示例,并希望显示总活动会话。所以我创建了@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
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(@NotNull WebSocketHandlerRegistry registry) {
        registry.addHandler(new Monitoring(), "/socket");
    }
}

由于conflict描述,自定义调度程序:

@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;
    }
}

1 个答案:

答案 0 :(得分:1)

您目前有Monitoring类的2个单独实例。一个由您自己创建,执行请求处理(不是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();
    }
}

您现在拥有一个由Spring管理的bean实例。