構建 Spring Integration 4.1 WebSocket 端點

工程 | Pieter Humphrey | 2014 年 11 月 15 日 | ...

作者:Josh Long

Spring Integration 4.1 剛剛釋出,它包含很多很棒的新功能!我最喜歡的功能之一?與 Spring 4 WebSocket 支援的智慧整合。現在您可以組合一個整合流,其最終目的地是 WebSocket 客戶端。還支援充當 WebSocket 服務的客戶端。

為了編譯它,您需要 Java 8(我們在這裡大量使用 lambda)和以下 Maven 依賴項

  • groupId:org.springframework.integration, artifactId:spring-integration-java-dsl, version: 1.0.0.RC1
  • groupId:org.springframework.integration, artifactId:spring-integration-websocket, version: 4.1.0.RELEASE
  • groupId:org.springframework.boot, artifactId:spring-boot-starter-websocket, version: 1.2.0.RC1

為了解決這些依賴關係,您需要 snapshotmilestone Maven 儲存庫。

所有監聽 /names 的客戶端都將收到傳送到 requestChannel 通道的任何訊息。Spring 4 MessageChannel 是一個命名的管道——或多或少類似於 java.util.Queue<T>。此示例在新的 Spring Integration 4.1 web socket 支援之上使用 Spring Integration Java 配置 DSL。這是示例

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很簡單。對於每個傳入的訊息,複製它並透過新增一個包含 SimpMessageHeaderAccessor.SESSION_ID_HEADER 的標頭來將其定址到每個偵聽的 WebSocket 會話,然後將其傳送到出站 webSocketOutboundAdapter,這將把它傳遞給每個偵聽的客戶端。要檢視它的工作原理,在一個瀏覽器視窗中開啟 https://:8080/,然後在另一個瀏覽器視窗中開啟 https://:8080/hi/Spring。有一個簡單的客戶端在這個技巧的程式碼倉庫中演示

Spring Integration 4.1 文件中有很多關於如何使用 web socket 元件的文件。在Spring Integration 示例目錄中也有一個更鼓舞人心的例子。

獲取 Spring 新聞簡報

與 Spring 新聞簡報保持聯絡

訂閱

取得領先

VMware 提供培訓和認證,以加速您的進步。

瞭解更多

獲得支援

Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案。

瞭解更多

即將舉行的活動

檢視 Spring 社群中所有即將舉行的活動。

檢視全部