对于最新稳定版本,请使用 Spring Integration 7.0.0spring-doc.cadn.net.cn

WebSockets 支持

从 4.1 版本开始,Spring Integration 支持了 WebSocket。 它基于 Spring 框架的架构、基础设施和 API网页套接字模块。 因此,许多 Spring WebSocket 的组件(例如子协议处理程序WebSocket客户端)和配置选项(例如@EnableWebSocketMessageBroker)可以在Spring Integration中重复使用。 欲了解更多信息,请参阅 Spring Framework 参考手册中的 WebSocket 支持章节。spring-doc.cadn.net.cn

你需要把这种依赖性纳入你的项目中:spring-doc.cadn.net.cn

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-websocket</artifactId>
    <version>6.2.11</version>
</dependency>
compile "org.springframework.integration:spring-integration-websocket:6.2.11"

对于服务器端,org.springframework:spring-webmvc依赖必须明确包含。spring-doc.cadn.net.cn

Spring Framework WebSocket 基础设施基于 Spring 消息传递基础,并基于该基础提供基本消息框架消息频道实现和消息处理器Spring Integration 使用的实现(以及一些 POJO 方法注释映射)。 因此,即使没有WebSocket适配器,Spring集成也可以直接参与WebSocket流程。 为此,你可以配置一个 Spring 集成@MessagingGateway并配有相应的注释,如下示例所示:spring-doc.cadn.net.cn

@MessagingGateway
@Controller
public interface WebSocketGateway {

    @MessageMapping("/greeting")
    @SendToUser("/queue/answer")
    @Gateway(requestChannel = "greetingChannel")
    String greeting(String payload);

}

概述

由于WebSocket协议本质上是流式的,我们可以同时与WebSocket发送和接收消息,因此我们可以处理适当的WebSocketSession无论客户端还是服务器端。 为了封装连接管理和WebSocketSession登记处,该集成WebSocket容器提供ClientWebSocketContainerServerWebSocketContainer实现。 得益于 WebSocket API 及其在 Spring 框架中的实现(带有许多扩展),服务器端和客户端(当然是从 Java 角度)都能使用相同的类。 因此,大多数联系和WebSocketSession双方的注册表选项是相同的。 这让我们能够重用许多配置项目和基础设施钩子,在服务器端和客户端构建WebSocket应用。 以下示例展示了组件如何同时满足这两个目的:spring-doc.cadn.net.cn

//Client side
@Bean
public WebSocketClient webSocketClient() {
    return new SockJsClient(Collections.singletonList(new WebSocketTransport(new JettyWebSocketClient())));
}

@Bean
public IntegrationWebSocketContainer clientWebSocketContainer() {
    return new ClientWebSocketContainer(webSocketClient(), "ws://my.server.com/endpoint");
}

//Server side
@Bean
public IntegrationWebSocketContainer serverWebSocketContainer() {
    return new ServerWebSocketContainer("/endpoint").withSockJs();
}

集成WebSocket容器设计用于实现双向消息传递,可以在进站和出站通道适配器之间共享(见下文),使用单向(发送或接收)WebSocket消息时,只能从其中一个适配器引用。 它可以不使用任何通道适配器,但在这种情况下,集成WebSocket容器仅作为WebSocketSession注册表。spring-doc.cadn.net.cn

ServerWebSocketContainer实现WebSocketConfigurer用来注册内部IntegrationWebSocketContainer.IntegrationWebSocketHandler作为端点. 它根据以下条件进行路径以及其他服务器WebSocket选项(例如)握手处理者SockJS 的备份)在ServletWebSocketHandlerRegistry针对目标厂商WebSocket容器。 这种注册是通过基础设施实现的WebSocketIntegrationConfigurationInitializer组件,其功能与@EnableWebSocket注解。 这意味着,通过@EnableIntegration(或应用上下文中的任何 Spring Integration 命名空间),你可以省略@EnableWebSocket声明,因为 Spring 集成基础设施检测所有 WebSocket 端点。

从6.1版本开始,ClientWebSocketContainer可以配置为URI而不是uri模板uri变量组合。 这在需要对某些 URI 部分进行自定义编码的情况下非常有用。 参见UriComponents构建器为了方便。spring-doc.cadn.net.cn

WebSocket 入站通道适配器

WebSocketInboundChannelAdapter实现接收部分WebSocketSession互动。 你必须为它提供一个集成WebSocket容器,适配器会将自己注册为WebSocketListener(WebSocketListener)用于处理来电消息和WebSocketSession事件。spring-doc.cadn.net.cn

只有一个WebSocketListener(WebSocketListener)可以注册在集成WebSocket容器.

对于WebSocket子协议,以下内容WebSocketInboundChannelAdapter可以配置为子协议处理注册表作为第二个构造子论证。 适配器会委派给子协议处理注册表以确定合适的子协议处理程序为了被接受的WebSocketSession并且要转换WebSocketMessage转给消息根据子协议实现。spring-doc.cadn.net.cn

默认情况下,WebSocketInboundChannelAdapter仅依赖RAW(原始数据)PassThruSubProtocolHandler实现,该实现将WebSocketMessage转给消息.

WebSocketInboundChannelAdapter接受并仅发送到底层积分流消息具有SimpMessageType.MESSAGE或者空的simpMessage类型页眉。 其他所有消息类型通过ApplicationEvent从一个子协议处理程序实现(例如:StompSubProtocolHandler).spring-doc.cadn.net.cn

在服务器端,如果@EnableWebSocketMessageBroker配置已经存在,你可以配置WebSocketInboundChannelAdapter其中useBroker = 真选择。 在这种情况下,所有非消息 消息类型被委派给提供的摘要代理消息处理器. 此外,如果中继配置了目的前缀,匹配经纪人目的地的消息会被路由到摘要代理消息处理器而不是输出通道关于WebSocketInboundChannelAdapter.spring-doc.cadn.net.cn

如果useBroker = false而接收到的消息是SimpMessageType.CONNECT类型,WebSocketInboundChannelAdapter立即发送SimpMessageType.CONNECT_ACKWebSocketSession没有发送到频道。spring-doc.cadn.net.cn

Spring 的 WebSocket 支持只允许配置一个代理继电器。 因此,我们不需要摘要代理消息处理器参考。 它在应用上下文中被检测到。

更多配置选项,请参见WebSockets命名空间支持spring-doc.cadn.net.cn

WebSocket 出站通道适配器

WebSocket 外接通道适配器:spring-doc.cadn.net.cn

  1. 接受来自其的 Spring 集成消息消息频道spring-doc.cadn.net.cn

  2. 确定WebSocketSession 身份证来自消息头spring-doc.cadn.net.cn

  3. 检索WebSocketSession来自提供的集成WebSocket容器spring-doc.cadn.net.cn

  4. 委托转换和发送WebSocketMessage工作内容为适当子协议处理程序来自提供的子协议处理注册表.spring-doc.cadn.net.cn

在客户端,WebSocketSession 身份证消息头不需要,因为ClientWebSocketContainer只处理单一连接及其WebSocketSession分别。spring-doc.cadn.net.cn

要使用 STOMP 子协议,你应该用StompSubProtocolHandler. 然后你可以向该适配器发送任意类型的STOMP消息,使用StompHeaderAccessor.create(StompCommand...)以及一个消息构建器,或者仅仅使用HeaderEnricher(参见标题增强器spring-doc.cadn.net.cn

本章其余部分主要涵盖更多配置选项。spring-doc.cadn.net.cn

WebSockets 命名空间支持

Spring Integration WebSocket 命名空间包含本章其余部分描述的多个组件。 要将其包含在配置中,请在应用上下文配置文件中使用以下命名空间声明:spring-doc.cadn.net.cn

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:int="http://www.springframework.org/schema/integration"
  xmlns:int-websocket="http://www.springframework.org/schema/integration/websocket"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/integration
    https://www.springframework.org/schema/integration/spring-integration.xsd
    http://www.springframework.org/schema/integration/websocket
    https://www.springframework.org/schema/integration/websocket/spring-integration-websocket.xsd">
    ...
</beans>

<int-websocket:client-container>属性

以下列表展示了<int-websocket:client-container>元素:spring-doc.cadn.net.cn

<int-websocket:client-container
                  id=""                             (1)
                  client=""                         (2)
                  uri=""                            (3)
                  uri-variables=""                  (4)
                  origin=""                         (5)
                  send-time-limit=""                (6)
                  send-buffer-size-limit=""         (7)
                  send-buffer-overflow-strategy=""  (8)
                  auto-startup=""                   (9)
                  phase="">                        (10)
                <int-websocket:http-headers>
                  <entry key="" value=""/>
                </int-websocket:http-headers>      (11)
</int-websocket:client-container>
1 成分豆的名字。
2 WebSocket客户端比恩的引用。
3 乌里uri模板连接到目标WebSocket服务。 如果你把它当作uri模板使用URI变量占位符时,URI变量需要属性。
4 URI变量占位符的逗号分隔值乌里属性值。 这些值根据在乌里. 看UriComponents.expand(Object...uriVariableValues).
5 起源握手HTTP头值。
6 WebSocket会话的“发送”超时限制。 默认10000.
7 WebSocket会话的“发送”消息大小限制。 默认524288.
8 WebSocket会话发送缓冲区溢出策略 当会话的出站消息缓冲区达到发送缓冲区大小限制. 看ConcurrentWebSocketSessionDecorator.OverflowStrategy以获取可能的数值和更多细节。
9 布尔值,表示该端点是否应自动启动。默认为false,假设该容器是从WebSocket的入站适配器启动的。
10 该端点应在生命周期内开始和结束的阶段。值越低,该端点开始得越早,停止越晚。默认为Integer.MAX价值. 数值可能是负的。 看智能生命周期.
11 一个地图HttpHeaders用于与握手请求一起使用。

<int-websocket:server-container>属性

以下列表展示了<int-websocket:server-container>元素:spring-doc.cadn.net.cn

<int-websocket:server-container
          id=""                             (1)
          path=""                           (2)
          handshake-handler=""              (3)
          handshake-interceptors=""         (4)
          decorator-factories=""            (5)
          send-time-limit=""                (6)
          send-buffer-size-limit=""         (7)
          send-buffer-overflow-strategy=""  (8)
          allowed-origins="">               (9)
          <int-websocket:sockjs
            client-library-url=""          (10)
            stream-bytes-limit=""          (11)
            session-cookie-needed=""       (12)
            heartbeat-time=""              (13)
            disconnect-delay=""            (14)
            message-cache-size=""          (15)
            websocket-enabled=""           (16)
            scheduler=""                   (17)
            message-codec=""               (18)
            transport-handlers=""          (19)
            suppress-cors="true" />        (20)
</int-websocket:server-container>
1 成分豆的名字。
2 一条将特定请求映射到一个WebSocketHandler. 支持精确路径映射URI(例如:/我的路径)和蚁式路径模式(例如/我的道路/**).
3 握手处理者比恩的引用。 默认默认握手处理器.
4 列表握手拦截者豆豆的致敬。
5 一个或多个工厂列表(WebSocketHandlerDecoratorFactory)装饰用于处理WebSocket消息的处理器。 这对某些高级用例可能有用(例如允许 Spring Security 强制关闭 当对应的HTTP会话到期时,WebSocket会话也就此变通)。 更多信息请参见春季课程项目
6 请参见相同的选项<int-websocket:client-container>.
7 请参见相同的选项<int-websocket:client-container>.
8 WebSocket会话发送缓冲区溢出策略 当会话的出站消息缓冲区达到发送缓冲区大小限制. 看ConcurrentWebSocketSessionDecorator.OverflowStrategy以获取可能的数值和更多细节。
9 允许的原点头值。 你可以用逗号分隔的列表指定多个起源。 这种检查主要面向浏览器客户端。 没有任何机制阻止其他类型的客户端修改原始头值。 当启用SockJS并限制起始点时,不使用起始点头进行跨起始请求的传输类型(jsonp-polling,iframe-xhr-polling,iframe-eventsourceiframe-htmlfile)被遗忘。 因此,IE6和IE7不被支持,IE8和IE9仅支持无Cookie。 默认情况下,所有起源都被允许。
10 没有原生跨域通信的传输(例如事件来源HTML文件)必须从“外”域获取一个简单的页面,在一个不可见的iframe中,这样iframe中的代码才能从SockJS服务器本地域运行。 由于 iframe 需要加载 SockJS JavaScript 客户端库,这个属性允许你指定加载位置。 默认情况下,它指向d1fxtkz8shb9d2.cloudfront.net/sockjs-0.3.4.min.js. 不过,你也可以设置它指向应用程序提供的URL。 注意,可以指定一个相对 URL,此时该 URL 必须相对于 iframe URL 进行。 例如,假设一个 SockJS 端点映射到/sockjs所得的iframe网址为/sockjs/iframe.html,相对URL必须以“../../“ 以遍历到 SockJS 映射上方的位置。 对于基于前缀的servlet映射,你可能需要再做一次遍历。
11 在关闭前,单个HTTP流请求可以发送的最小字节数。 默认128K(即128*1024或131072字节)。
12 cookie_neededSockJs的回答中体现了价值/信息端点。 该性质表示JSESSIONIDCookie 是应用程序正常运行的必要条件(例如用于负载均衡或在 Java Servlet 容器中用于 HTTP 会话)。
13 服务器没有发送任何消息的时间(以毫秒为单位),之后服务器应该发送 向客户端发送心跳帧,以防止连接中断。 默认值为25,000(25秒)。
14 客户端在没有接收连接(即服务器可通过该连接向客户端发送数据的活跃连接)后被视为断开连接的时间(以毫秒计)。 默认值为5000.
15 会话在等待客户端下一次HTTP轮询请求时,可以缓存的服务器到客户端消息数量。 默认大小为100.
16 部分负载均衡器不支持 WebSockets。 将此选项设置为false禁用服务器端的WebSocket传输。 默认值为true.
17 任务调度器比恩的引用。 一个新的ThreadPoolTaskScheduler如果没有提供价值,实例就会被创建。 该调度器实例用于调度心跳消息。
18 SockJsMessageCodec用于编码和解码SockJS消息的bean引用。 默认情况下,Jackson2SockJsMessageCodec被使用,这需要Jackson库存在于类路径上。
19 列表传输处理器豆豆的致敬。
20 是否关闭 SockJS 请求自动添加 CORS 头部。 默认值为false.

<int-websocket:出站通道适配器>属性

以下列表展示了<int-websocket:出站通道适配器>元素:spring-doc.cadn.net.cn

<int-websocket:outbound-channel-adapter
                          id=""                             (1)
                          channel=""                        (2)
                          container=""                      (3)
                          default-protocol-handler=""       (4)
                          protocol-handlers=""              (5)
                          message-converters=""             (6)
                          merge-with-default-converters=""  (7)
                          auto-startup=""                   (8)
                          phase=""/>                        (9)
1 成分豆的名字。 如果您不提供渠道属性,a直达频道在应用上下文中创建并注册了身份证属性为豆名。在这种情况下,端点被注册为豆名身份证。适配器. 而且消息处理器注册时使用Bean别名身份证。处理器.
2 识别连接到该适配器的通道。
3 集成WebSocket容器BEAN,封装了低层连接和WebSocketSession负责运营。 必填。
4 可选引用子协议处理程序实例。 当客户端未请求子协议或仅为单一协议处理程序时,使用该程序。 如果这个引用或协议处理程序未提供列表,PassThruSubProtocolHandler默认使用。
5 列表子协议处理程序该通道适配器的BEAN参考。 如果你只提供一个豆子的参考资料,而没有提供默认协议处理程序,那首单曲子协议处理程序被用作默认协议处理程序. 如果您未设置此属性或默认协议处理程序PassThruSubProtocolHandler默认使用。
6 列表消息转换器该通道适配器的BEAN参考。
7 布尔值表示默认转换器是否应在任何自定义转换器之后注册。 该旗帜仅在消息转换器是提供的。否则,所有默认转换器都会被注册。默认为false. 默认转换器依次为:字符串消息转换器,字节阵列消息转换器MappingJackson2Message转换器(如果 Jackson 库存在于类路径中)。
8 布尔值,表示该端点是否应自动启动。默认为true.
9 该端点应在生命周期内开始和结束的阶段。值越低,该端点开始得越早,停止越晚。默认为Integer.MIN_VALUE. 数值可能是负的。 看智能生命周期.

<in-websocket:inbound-channel-adapter>属性

以下列表展示了<int-websocket:出站通道适配器>元素:spring-doc.cadn.net.cn

<int-websocket:inbound-channel-adapter
                            id=""  (1)
                            channel=""  (2)
                            error-channel=""  (3)
                            container=""  (4)
                            default-protocol-handler=""  (5)
                            protocol-handlers=""  (6)
                            message-converters=""  (7)
                            merge-with-default-converters=""  (8)
                            send-timeout=""  (9)
                            payload-type=""  (10)
                            use-broker=""  (11)
                            auto-startup=""  (12)
                            phase=""/>  (13)
1 组件豆名。如果你没有设置渠道属性,a直达频道在应用上下文中创建并注册了身份证属性为豆名。在这种情况下,端点被注册为豆名身份证。适配器.
2 识别连接到该适配器的通道。
3 消息频道比恩引用错误消息实例应该被发送。
4 请参见相同的选项<int-websocket:出站通道适配器>.
5 请参见相同的选项<int-websocket:出站通道适配器>.
6 请参见相同的选项<int-websocket:出站通道适配器>.
7 请参见相同的选项<int-websocket:出站通道适配器>.
8 请参见相同的选项<int-websocket:出站通道适配器>.
9 如果信道能阻塞,发送消息时等待的最大时间(以毫秒为单位)。例如,队列通道如果容量已达到最大,则可以阻塞直到空间可用。
10 目标的 Java 类型完全限定名称有效载荷从输入中转换WebSocketMessage. 默认java.lang.字符串.
11 表示该适配器是否发送非消息 WebSocketMessage带有经纪人目的地的实例和消息摘要代理消息处理器从应用上下文中。当该属性为true经纪人中继需要配置。该属性仅用于服务器端。客户端则忽略。默认为false.
12 请参见相同的选项<int-websocket:出站通道适配器>.
13 请参见相同的选项<int-websocket:出站通道适配器>.

ClientStompEncoder

从4.3.13版本开始,Spring Integration提供了ClientStompEncoder(作为标准的扩展Stomp编码器)用于WebSocket通道适配器的客户端。为了正确准备客户端消息,您必须注入一个实例ClientStompEncoder进入StompSubProtocolHandler. 默认的一个问题StompSubProtocolHandler它是为服务器端设计的,因此它会更新发送 stompCommand(STOMP踏指令)标题进入消息(根据STOMP协议对服务器端的要求)。如果客户端没有按正确方式发送消息发送Web socket 帧,一些 STOMP 代理不接受它们。目的ClientStompEncoder,在此情况下,是覆盖stompCommand(STOMP踏指令)并设置为发送在将消息编码为字节[].spring-doc.cadn.net.cn

动态WebSocket端点注册

从5.5版本开始,WebSocket服务器端点(基于ServerWebSocketContainer)现在可以在运行时注册(并移除)——路径一个ServerWebSocketContainer映射为 通过处理器映射变成了调度器服务并对WebSocket客户端开放。动态集成和运行时集成流程支持有助于以透明方式注册这些端点:spring-doc.cadn.net.cn

@Autowired
IntegrationFlowContext integrationFlowContext;

@Autowired
HandshakeHandler handshakeHandler;
...
ServerWebSocketContainer serverWebSocketContainer =
       new ServerWebSocketContainer("/dynamic")
               .setHandshakeHandler(this.handshakeHandler);

WebSocketInboundChannelAdapter webSocketInboundChannelAdapter =
       new WebSocketInboundChannelAdapter(serverWebSocketContainer);

QueueChannel dynamicRequestsChannel = new QueueChannel();

IntegrationFlow serverFlow =
       IntegrationFlow.from(webSocketInboundChannelAdapter)
               .channel(dynamicRequestsChannel)
               .get();

IntegrationFlowContext.IntegrationFlowRegistration dynamicServerFlow =
       this.integrationFlowContext.registration(serverFlow)
               .addBean(serverWebSocketContainer)
               .register();
...
dynamicServerFlow.destroy();
打电话很重要.addBean(serverWebSocketContainer)在动态流注册上加入ServerWebSocketContainer变成了应用上下文用于端点注册。当动态流注册被销毁时,关联的ServerWebSocketContainer实例以及相应的端点注册(包括URL路径映射)也会被销毁。
动态Websocket端点只能通过Spring集成机制注册:当普通Spring@EnableWebsocket使用时,Spring 集成配置会退后,且没有注册任何动态端点基础设施。