spring 注册动态 ServerWebSocketContainer 路径的集成,因此可以使用不同的路径创建不同的集成流

spring integration to register dynamic ServerWebSocketContainer paths so different integration flows can be created with different paths

@Component
public class WebSocketRegistration {

  @Autowired
  GenericWebApplicationContext context;
  @Autowired
  private IntegrationFlowContext flowContext;

  public String registerServerEndpoint(String beanName, String endPoint) {
    context.registerBean(beanName, ServerWebSocketContainer.class,
        () -> new ServerWebSocketContainer(endPoint).withSockJs(),
        beanDefinition -> beanDefinition.setAutowireCandidate(true));
    return beanName;
  }

  public StandardIntegrationFlow webSocketFlow(String beanName) {
    ServerWebSocketContainer serverWebSocketContainer = (ServerWebSocketContainer) context
        .getBean(beanName);
    WebSocketOutboundMessageHandler webSocketOutboundMessageHandler = new WebSocketOutboundMessageHandler(
        serverWebSocketContainer);
    StandardIntegrationFlow flow = IntegrationFlows.from("stringChannel")
        .split(new AbstractMessageSplitter() {
          @Override
          protected Object splitMessage(Message<?> message) {

            return serverWebSocketContainer
                .getSessions()
                .keySet()
                .stream()
                .map(s -> {
                  System.out.println(message.getPayload().toString() + " and key " + s);
                  return MessageBuilder.fromMessage(message)
                      .setHeader(SimpMessageHeaderAccessor.SESSION_ID_HEADER, s)
                      .build();
                })
                .collect(Collectors.toList());
          }
        })
        .handle(webSocketOutboundMessageHandler).get();

    String id = flowContext.registration(flow).register().getId();
    System.out.println(id);
    return flow;
  }
}

这是注册集成流程的示例代码,以便 websocket 可以在运行时将数据发布到指定的端点。我不确定 spring websocket 是否允许它,但是当我在运行时使用不同的 websocket url 注册流时它不会抛出任何错误。

目前无法动态 ServerWebSocketContainer bean 注册。 它与应用程序上下文初始化阶段完全相关。

即使您在通过 context.registerBean() 注册该 bean 时没有遇到任何错误,HandlerMapping 也不会针对新路径及其映射进行更新。

当您尝试从容器中选择会话以决定向谁发送消息时,我建议您查看通用 ServerWebSocketContainer 和一些“选择器”逻辑。

随时提出 GH 问题以改进 Spring 集成中的 WebSocket 支持。 事实上,我们现在有动态 HTTP 和 WebFlux 注册。