我使用 Spring WebSocket 和 STOMP 在我的服务器和客户端之间建立 WebSocket 连接,客户端在前端使用 stomp.js。当选项卡处于活动状态时,我的应用程序运行良好,但如果浏览器选项卡变为非活动状态(例如,如果用户切换选项卡或最小化浏览器),则 WebSocket 连接会在一段时间后断开连接。这种断开连接似乎是许多现代浏览器的内置功能。
为了保持连接处于活动状态,我在 Spring WebSocket 配置中启用了心跳机制。我的服务器配置为向客户端发送定期心跳或从客户端接收定期心跳,但这种方法并不能有效地防止选项卡处于非活动状态时关闭连接。
我已经广泛研究了这个问题,并了解到当选项卡处于非活动状态时,基于浏览器的 WebSocket 断开连接可能很难防止。然而,我找不到在不同浏览器上可靠工作的具体解决方案。这是我当前在服务器上的 WebSocket 配置:
@Configuration
@EnableWebSocketMessageBroker
@ConditionalOnExpression("${enable-websocket:false}")
@Slf4j
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Value("${websocket.simple-broker.destinations}")
private String[] simpleBrokerDestinations;
@Value("${websocket.application-destination.prefixes}")
private String applicationDestinationPrefixes;
@Value("${websocket.endpoint}")
private String websocketEndpoint;
@Value("${websocket.allowed-origin-patterns}")
private String[] allowedOriginPatterns;
@Value("${websocket.server.heartbeat:30000}")
private Long serverHeartbeat;
@Value("${websocket.client.heartbeat:30000}")
private Long clientHeartbeat;
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
ThreadPoolTaskScheduler websocketHeartbeatTaskScheduler = websocketHeartbeatTaskScheduler();
registry.enableSimpleBroker(simpleBrokerDestinations)
.setHeartbeatValue(new long[]{serverHeartbeat, clientHeartbeat})
.setTaskScheduler(websocketHeartbeatTaskScheduler);
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint(websocketEndpoint)
.setAllowedOriginPatterns(allowedOriginPatterns)
.addInterceptors();
}
@Bean
public ThreadPoolTaskScheduler websocketHeartbeatTaskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(1);
scheduler.setThreadNamePrefix(Thread.currentThread().getStackTrace()[1].getMethodName());
scheduler.initialize();
return scheduler;
}
}
我的问题:Spring WebSocket 中是否有任何解决方法或配置可以可靠地防止选项卡处于非活动状态时断开连接?即使心跳机制不能,从客户端实施自定义定期 ping 是否有助于保持连接处于活动状态?如果是这样,如何通过
stomp.js
实现这一目标?
在无法避免断开连接的情况下,是否有其他方法可以在重新激活选项卡时处理重新建立连接并重新同步丢失的消息?我非常感谢可能面临类似挑战的其他人的任何指导或建议。
这对你来说应该不是问题,你只需要在用户返回时自动重新连接,如果你使用的是 js 客户端,这应该自动完成