升级到 Spring Boot 3.3.5 后,WebSocketMessageBroker 无法按预期工作

问题描述 投票:0回答:1

我有一个使用以下配置公开 WebSocket 端点的应用程序

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

  public static final String WS_ENDPOINT = "/notifications/v1";
  public static final String EVENTS_CHANNEL = "/events";
  public static final String ERRORS_CHANNEL = "/errors";

  @Autowired
  private StompMessageChannelInterceptor stompMessageChannelInterceptor;

  @Override
  public void registerStompEndpoints(final StompEndpointRegistry registry) {
    registry.addEndpoint(WS_ENDPOINT)
            .setAllowedOrigins("*")
            .addInterceptors(new WebsocketHandshakeInterceptor())
            .setHandshakeHandler(new WebsocketHandshakeInterceptor());
  }

  @Override
  public void configureMessageBroker(final MessageBrokerRegistry registry) {
    registry.enableSimpleBroker(EVENTS_CHANNEL, ERRORS_CHANNEL);
  }

  @Override
  public void configureClientInboundChannel(final ChannelRegistration registration) {
    registration.interceptors(stompMessageChannelInterceptor);
  }

  @Override
  public void configureWebSocketTransport(final WebSocketTransportRegistration registration) {
    registration.addDecoratorFactory(new WebSocketHandlerDecoratorFactory() {
      @Override
      public WebSocketHandler decorate(final WebSocketHandler webSocketHandler) {
          return new WebSocketSessionCapturingHandlerDecorator(webSocketHandler);
      }
    });
  }
}

该配置在 Spring Boot 2.7.18 上运行良好。但迁移到 Spring Boot 3.3.5 后,

WebSocketMessagingAutoConfiguration
设置
AsyncTaskExecutor
。自动配置(在
WebSocketMessagingAutoConfiguration.WebSocketMessageConverterConfiguration
中)采用了我们自定义的
AsyncTaskExecutor
实现,这不适合 WebSocket 配置(它为可运行任务添加了一些额外的逻辑)。下面是自动配置拾取的
AsyncTaskExecutor
的实现

public class ApiPoolExecutor extends ThreadPoolTaskExecutor {

  private static final long serialVersionUID = 1L;

  @Override
  public Future<?> submit(final Runnable task) {
    return super.submit(new SomeLogicForRunnable(task));
  }


  @Override
  public ListenableFuture<?> submitListenable(final Runnable task) {
    return super.submitListenable(new SomeLogicForRunnable(task));
  }

  @Override
  public <T> ListenableFuture<T> submitListenable(final Callable<T> task) {
    return super.submitListenable(new SomeLogicForRunnable(task));
  }

  @Override
  public void execute(final Runnable task) {
    super.execute(new SomeLogicForRunnable(task));
  }
}

我尝试创建

AsyncTaskExecutor
的另一个实现,没有围绕可运行任务的任何额外逻辑,但
Autoconfiguration
仍然只看到 ApiPoolExecutor 实现。我还尝试将执行器直接设置在我的
ChannelRegistration
中的
WebSocketConfig

  @Override
  public void configureClientInboundChannel(final ChannelRegistration registration) {
    registration.interceptors(stompMessageChannelInterceptor);
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setMaxPoolSize(100);
    executor.setCorePoolSize(100);
    executor.setBeanName("ws-pool-exec");
    executor.initialize();
    registration.executor(new WebSocketTaskPoolExecutor());
  }

但稍后自动配置会使用

ApiPoolExecutor
覆盖该执行器。如何使自动配置不覆盖
ChannelRegistration
上的执行器?或者如何完全禁用它?

java spring-boot spring-ws spring-messaging
1个回答
0
投票

我通过创建自己的 ThreadPoolTaskExecutor 作为命名 bean 来修复它。 Bean 名称应与 WebSocketMessagingAutoConfiguration.WebSocketMessageConverterConfiguration 类中的 certainAsyncTaskExecutor() 方法所需的名称相对应

  @Bean (name = TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)
  public ThreadPoolTaskExecutor getApplicationTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setMaxPoolSize(100);
    executor.setCorePoolSize(100);
    executor.setBeanName("ws-pool-exec");
    executor.initialize();
    return executor;
  }
© www.soinside.com 2019 - 2024. All rights reserved.