Статьи

Создание Spring Integration 4.1 WebSocket Endpoint

Первоначально автор  Джош Лонг   в блоге Spring

Spring Integration 4.1  был только что выпущен и включает в себя множество замечательных новых функций! Один из любимых? Интеллектуальная интеграция с поддержкой Spring 4 WebSocket. Теперь вы можете составить поток интеграции, конечным пунктом назначения которого является клиент WebSocket. Существует также поддержка для работы в качестве клиента для службы WebSocket.

Чтобы скомпилировать его, вам потребуется Java 8 (здесь мы широко используем lambas) и следующие зависимости Maven:

  • идентификатор_группы: org.springframework.integration, артефакт: spring-integration-java-dslверсия:  1.0.0.RC1.
  • идентификатор_группы: org.springframework.integration, артефакт: spring-integration-websocketверсия:  4.1.0.RELEASE.
  • идентификатор_группы: org.springframework.boot, артефакт: spring-boot-starter-websocketверсия:  1.2.0.RC1.

Для разрешения этих зависимостей вам понадобятся   репозитории snapshot и  milestoneMaven.

Все прослушивающие клиенты  /names получат все сообщения, отправленные на requestChannel канал. Spring 4  MessageChannel — это именованный канал, более или менее аналогичный a  java.util.Queue<T>. В этом примере используется  DSL конфигурации Spring Integration Java  поверх новой  поддержки веб-сокетов Spring Integration 4.1 . Вот пример:

package demo ;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.*;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.support.Function;
import org.springframework.integration.websocket.ServerWebSocketContainer;
import org.springframework.integration.websocket.outbound.WebSocketOutboundMessageHandler;
import org.springframework.messaging.*;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @author Artem Bilan
 * @author Josh Long
 */
@Configuration
@ComponentScan
@EnableAutoConfiguration
@RestController
public class Application {

    public static void main(String args[]) throws Throwable {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    ServerWebSocketContainer serverWebSocketContainer() {
        return new ServerWebSocketContainer("/names").withSockJs();
    }

    @Bean
    MessageHandler webSocketOutboundAdapter() {
        return new WebSocketOutboundMessageHandler(serverWebSocketContainer());
    }

    @Bean(name = "webSocketFlow.input")
    MessageChannel requestChannel() {
        return new DirectChannel();
    }

    @Bean
    IntegrationFlow webSocketFlow() {
        return f -> {
            Function<Message , Object> splitter = m -> serverWebSocketContainer()
                    .getSessions()
                    .keySet()
                    .stream()
                    .map(s -> MessageBuilder.fromMessage(m)
                            .setHeader(SimpMessageHeaderAccessor.SESSION_ID_HEADER, s)
                            .build())
                    .collect(Collectors.toList());
            f.split( Message.class, splitter)
                    .channel(c -> c.executor(Executors.newCachedThreadPool()))
                    .handle(webSocketOutboundAdapter());
        };
    }

    @RequestMapping("/hi/{name}")
    public void send(@PathVariable String name) {
        requestChannel().send(MessageBuilder.withPayload(name).build());
    }
}

Это  IntegrationFlow просто. Для каждого входящего сообщения скопируйте его и направьте его в каждый WebSocket сеанс прослушивания  , добавив заголовок, имеющий SimpMessageHeaderAccessor.SESSION_ID_HEADER, затем отправьте исходящий, webSocketOutboundAdapter который доставит его каждому прослушивающему клиенту. Чтобы увидеть, как это работает, откройте http://localhost:8080/ в одном окне браузера, а затем http://localhost:8080/hi/Spring в другом. В этом репозитории кода Techtip есть простой клиент  .

В документации по Spring Integration 4.1 есть отличная документация по использованию компонентов веб-сокетов  . В каталоге примеров Spring Integration также есть более вдохновляющий пример  .