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