WebSockets Support
从 4.1 版本开始,Spring Integration 支持 WebSocket。它基于 Spring Framework 的 web-socket`模块的架构、基础设施和 API。因此,Spring WebSocket 的许多组件(例如 `SubProtocolHandler`或 `WebSocketClient
)和配置选项(例如 @EnableWebSocketMessageBroker
)可以在 Spring Integration 中重复使用。有关详细信息,请参阅 Spring Framework 参考手册中的 Spring Framework WebSocket Support章节。
Starting with version 4.1, Spring Integration has WebSocket support.
It is based on the architecture, infrastructure, and API from the Spring Framework’s web-socket
module.
Therefore, many of Spring WebSocket’s components (such as SubProtocolHandler
or WebSocketClient
) and configuration options (such as @EnableWebSocketMessageBroker
) can be reused within Spring Integration.
For more information, see the Spring Framework WebSocket Support chapter in the Spring Framework reference manual.
你需要将此依赖项包含在你的项目中:
You need to include this dependency into your project:
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-websocket</artifactId>
<version>{project-version}</version>
</dependency>
compile "org.springframework.integration:spring-integration-websocket:{project-version}"
对于服务器端,org.springframework:spring-webmvc
依赖项必须显式包含。
For server side, the org.springframework:spring-webmvc
dependency must be included explicitly.
Spring Framework WebSocket 基础设施基于 Spring 消息基础,并提供了一个基于 Spring Integration 使用的相同 MessageChannel
实现和 MessageHandler
实现(以及一些 POJO 方法注释映射)的基本消息框架。因此,即使没有 WebSocket 适配器,Spring Integration 也可以直接参与 WebSocket 流。为此,你可以使用适当的注释来配置一个 Spring Integration @MessagingGateway
,如下面的示例所示:
The Spring Framework WebSocket infrastructure is based on the Spring messaging foundation and provides a basic messaging framework based on the same MessageChannel
implementations and MessageHandler
implementations that Spring Integration uses (and some POJO-method annotation mappings).
Consequently, Spring Integration can be directly involved in a WebSocket flow, even without WebSocket adapters.
For this purpose, you can configure a Spring Integration @MessagingGateway
with appropriate annotations, as the following example shows:
@MessagingGateway
@Controller
public interface WebSocketGateway {
@MessageMapping("/greeting")
@SendToUser("/queue/answer")
@Gateway(requestChannel = "greetingChannel")
String greeting(String payload);
}
Overview
由于 WebSocket 协议按定义为流式,并且我们可以同时向和来自 WebSocket 发送和接收消息,因此可以处理适当的 WebSocketSession
,无论是在客户端还是在服务器端。为了封装连接管理和 WebSocketSession
注册表,需通过 ClientWebSocketContainer
和 ServerWebSocketContainer
实现为 IntegrationWebSocketContainer
提供信息。借助 Spring 框架中的 WebSocket API 及其实现(包含许多扩展),在服务器端和客户端均使用相同的类(当然,这是从 Java 的角度来看的)。因此,在两端,大多数连接和 WebSocketSession
注册表选项都是相同的。这让我们可以重复使用许多配置项和基础架构挂钩,以便在服务器端和客户端上构建 WebSocket 应用程序。以下示例显示了组件如何同时服务于这两个目的:
Since the WebSocket protocol is streaming by definition, and we can send and receive messages to and from a WebSocket at the same time, we can deal with an appropriate WebSocketSession
, regardless of being on the client or server side.
To encapsulate the connection management and WebSocketSession
registry, the IntegrationWebSocketContainer
is provided with ClientWebSocketContainer
and ServerWebSocketContainer
implementations.
Thanks to the WebSocket API and its implementation in the Spring Framework (with many extensions), the same classes are used on the server side as well as the client side (from a Java perspective, of course).
Consequently, most connection and WebSocketSession
registry options are the same on both sides.
That lets us reuse many configuration items and infrastructure hooks to build WebSocket applications on the server side as well as on the client side.
The following example shows how components can serve both purposes:
//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();
}
IntegrationWebSocketContainer
旨在实现双向消息传递,可以在入站和出站通道适配器之间共享(见下文),在使用单向(发送或接收)WebSocket 消息传递时只能从中一个引用它。它可以在没有任何通道适配器的情况下使用,但是,在这种情况下,IntegrationWebSocketContainer
仅充当 WebSocketSession
注册表。
The IntegrationWebSocketContainer
is designed to achieve bidirectional messaging and can be shared between inbound and outbound channel adapters (see below), can be referenced from only one of them when using one-way (sending or receiving) WebSocket messaging.
It can be used without any channel adapter, but, in this case, IntegrationWebSocketContainer
only plays a role as the WebSocketSession
registry.
|
The |
从 6.1 版本开始,ClientWebSocketContainer
可通过提供的 URI
进行配置,而不是 uriTemplate
和 uriVariables
组合。在有些场景下需要对 URI 的某些部分进行自定义编码时,这种方式非常有用。较为便捷的方式是,参阅 UriComponentsBuilder
API。
Starting with version 6.1, the ClientWebSocketContainer
can be configured with a provided URI
instead of uriTemplate
and uriVariables
combination.
This is useful in cases when custom encoding is required for some parts of the uri.
See an UriComponentsBuilder
API for convenience.
WebSocket Inbound Channel Adapter
WebSocketInboundChannelAdapter
实现了 WebSocketSession
交互中的接收部分。你必须向它提供一个 IntegrationWebSocketContainer
并且该适配器将自己注册为一个 WebSocketListener
来处理传入的消息和 WebSocketSession
事件。
The WebSocketInboundChannelAdapter
implements the receiving part of WebSocketSession
interaction.
You must supply it with a IntegrationWebSocketContainer
, and the adapter registers itself as a WebSocketListener
to handle incoming messages and WebSocketSession
events.
只能在 |
Only one |
为 WebSocket 子协议,WebSocketInboundChannelAdapter
可以通过 SubProtocolHandlerRegistry
进行配置,SubProtocolHandlerRegistry
为第二个构造函数参数。该适配器委托给 SubProtocolHandlerRegistry
来根据已接受的 WebSocketSession
判断恰当的 SubProtocolHandler
,并将一个 WebSocketMessage
转换为一个 Message
,具体取决于子协议的实现。
For WebSocket sub-protocols, the WebSocketInboundChannelAdapter
can be configured with SubProtocolHandlerRegistry
as the second constructor argument.
The adapter delegates to the SubProtocolHandlerRegistry
to determine the appropriate SubProtocolHandler
for the accepted WebSocketSession
and to convert a WebSocketMessage
to a Message
according to the sub-protocol implementation.
默认情况下, |
By default, the |
WebSocketInboundChannelAdapter
仅接受和发送包含 SimpMessageType.MESSAGE
或一个空的 simpMessageType
头的 Message
实例到底层集成流。所有其他 Message
类型通过从 SubProtocolHandler
实现(如 StompSubProtocolHandler
)发出的 ApplicationEvent
实例来处理。
The WebSocketInboundChannelAdapter
accepts and sends to the underlying integration flow only Message
instances that have SimpMessageType.MESSAGE
or an empty simpMessageType
header.
All other Message
types are handled through the ApplicationEvent
instances emitted from a SubProtocolHandler
implementation (such as StompSubProtocolHandler
).
在服务器端,如果存在 @EnableWebSocketMessageBroker
配置,可以使用 useBroker = true
选项来配置 WebSocketInboundChannelAdapter
。在这种情况下,所有 非 MESSAGE
的 Message
类型都将委托给提供的 AbstractBrokerMessageHandler
。另外,如果代理中继使用 destination 前缀进行了配置,那么与代理目标匹配的消息会路由到 AbstractBrokerMessageHandler
,而不是 WebSocketInboundChannelAdapter
的 outputChannel
。
On the server side, if the @EnableWebSocketMessageBroker
configuration is present, you can configure WebSocketInboundChannelAdapter
with the useBroker = true
option.
In this case, all non-MESSAGE
Message
types are delegated to the provided AbstractBrokerMessageHandler
.
In addition, if the broker relay is configured with destination prefixes, those messages that match the Broker destinations are routed to the AbstractBrokerMessageHandler
instead of to the outputChannel
of the WebSocketInboundChannelAdapter
.
如果 useBroker = false
且接收的消息类型是 SimpMessageType.CONNECT
,那么 WebSocketInboundChannelAdapter
会立即向 WebSocketSession
发送一个 SimpMessageType.CONNECT_ACK
消息,而不会将它发送到通道。
If useBroker = false
and the received message is of the SimpMessageType.CONNECT
type, the WebSocketInboundChannelAdapter
immediately sends a SimpMessageType.CONNECT_ACK
message to the WebSocketSession
without sending it to the channel.
Spring 的 WebSocket 支持只允许配置一个代理中继。因此,不需要 |
Spring’s WebSocket Support allows the configuration of only one broker relay.
Consequently, we do not require an |
有关更多配置选项,请参见 WebSockets Namespace Support。
For more configuration options, see WebSockets Namespace Support.
WebSocket Outbound Channel Adapter
WebSocketOutboundChannelAdapter
:
The WebSocketOutboundChannelAdapter
:
-
Accepts Spring Integration messages from its
MessageChannel
-
Determines the
WebSocketSession
id
from theMessageHeaders
-
Retrieves the
WebSocketSession
from the providedIntegrationWebSocketContainer
-
Delegates the conversion and sending of
WebSocketMessage
work to the appropriateSubProtocolHandler
from the providedSubProtocolHandlerRegistry
.
在客户端,并不需要 WebSocketSession
的 id
消息头,因为 ClientWebSocketContainer
只处理单个连接和它各自的 WebSocketSession
。
On the client side, the WebSocketSession
id
message header is not required, because ClientWebSocketContainer
deals only with a single connection and its WebSocketSession
respectively.
要使用 STOMP 子协议,你应该使用 StompSubProtocolHandler`配置该适配器。然后你可以使用 `StompHeaderAccessor.create(StompCommand…)`和 `MessageBuilder`将任何 STOMP 消息类型发送到该适配器,或者只使用 `HeaderEnricher
(请参见 Header Enricher)。
To use the STOMP sub-protocol, you should configure this adapter with a StompSubProtocolHandler
.
Then you can send any STOMP message type to this adapter, using StompHeaderAccessor.create(StompCommand…)
and a MessageBuilder
, or just using a HeaderEnricher
(see Header Enricher).
本章的剩余部分主要涵盖附加配置选项。
The rest of this chapter covers largely additional configuration options.
WebSockets Namespace Support
Spring Integration WebSocket 命名空间包括本章剩余部分描述的几个组件。要将它包含在你的配置中,在你的应用程序上下文配置文件中使用以下命名空间声明:
The Spring Integration WebSocket namespace includes several components described in the remainder of this chapter. To include it in your configuration, use the following namespace declaration in your application context configuration file:
<?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>
Attributes
以下清单展示了 <int-websocket:client-container>
元素可用的属性:
The following listing shows the attributes available for the <int-websocket:client-container>
element:
<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 | The component bean name. |
2 | The WebSocketClient bean reference. |
3 | The uri or uriTemplate to the target WebSocket service.
If you use it as a uriTemplate with URI variable placeholders, the uri-variables attribute is required. |
4 | Comma-separated values for the URI variable placeholders within the uri attribute value.
The values are replaced into the placeholders according to their order in the uri .
See UriComponents.expand(Object…uriVariableValues) . |
5 | The Origin Handshake HTTP header value. |
6 | The WebSocket session 'send' timeout limit.
Defaults to 10000 . |
7 | The WebSocket session 'send' message size limit.
Defaults to 524288 . |
8 | The WebSocket session send buffer overflow strategy
determines the behavior when a session’s outbound message buffer has reached the send-buffer-size-limit .
See ConcurrentWebSocketSessionDecorator.OverflowStrategy for possible values and more details. |
9 | Boolean value indicating whether this endpoint should start automatically.
Defaults to false , assuming that this container is started from the WebSocket inbound adapter. |
10 | The lifecycle phase within which this endpoint should start and stop.
The lower the value, the earlier this endpoint starts and the later it stops.
The default is Integer.MAX_VALUE .
Values can be negative.
See SmartLifeCycle . |
11 | A Map of HttpHeaders to be used with the Handshake request. |
<int-websocket:server-container>
Attributes
以下清单展示了 <int-websocket:server-container>
元素可用的属性:
The following listing shows the attributes available for the <int-websocket:server-container>
element:
<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 | The component bean name. |
2 | A path (or comma-separated paths) that maps a particular request to a WebSocketHandler .
Supports exact path mapping URIs (such as /myPath ) and ant-style path patterns (such as /myPath/** ). |
3 | The HandshakeHandler bean reference.
Defaults to DefaultHandshakeHandler . |
4 | List of HandshakeInterceptor bean references. |
5 | List of one or more factories (WebSocketHandlerDecoratorFactory ) that decorate the handler used to process WebSocket messages.
This may be useful for some advanced use cases (for example, to allow Spring Security to forcibly close
the WebSocket session when the corresponding HTTP session expires).
See the Spring Session Project for more information. |
6 | See the same option on the <<`<int-websocket:client-container>`,websocket-client-container-attributes>>. |
7 | See the same option on the <<`<int-websocket:client-container>`,websocket-client-container-attributes>>. |
8 | The WebSocket session send buffer overflow strategy
determines the behavior when a session’s outbound message buffer has reached the send-buffer-size-limit .
See ConcurrentWebSocketSessionDecorator.OverflowStrategy for possible values and more details. |
9 | The allowed origin header values.
You can specify multiple origins as a comma-separated list.
This check is mostly designed for browser clients.
There is nothing preventing other types of client from modifying the origin header value.
When SockJS is enabled and allowed origins are restricted, transport types that do not use origin headers for cross-origin requests (jsonp-polling , iframe-xhr-polling , iframe-eventsource , and iframe-htmlfile ) are disabled.
As a consequence, IE6 and IE7 are not supported, and IE8 and IE9 are supported only without cookies.
By default, all origins are allowed. |
10 | Transports with no native cross-domain communication (such as eventsource and htmlfile ) must get a simple page from the “foreign” domain in an invisible iframe so that code in the iframe can run from a domain local to the SockJS server.
Since the iframe needs to load the SockJS javascript client library, this property lets you specify the location from which to load it.
By default, it points to https://d1fxtkz8shb9d2.cloudfront.net/sockjs-0.3.4.min.js .
However, you can also set it to point to a URL served by the application.
Note that it is possible to specify a relative URL, in which case the URL must be relative to the iframe URL.
For example, assuming a SockJS endpoint mapped to /sockjs and the resulting iframe URL is /sockjs/iframe.html , the relative URL must start with "../../" to traverse up to the location above the SockJS mapping.
For prefix-based servlet mapping, you may need one more traversal. |
11 | Minimum number of bytes that can be sent over a single HTTP streaming request before it is closed.
Defaults to 128K (that is, 128*1024 or 131072 bytes). |
12 | The cookie_needed value in the response from the SockJs /info endpoint.
This property indicates whether a JSESSIONID cookie is required for the application to function correctly (for example, for load balancing or in Java Servlet containers for the use of an HTTP session). |
13 | The amount of time (in milliseconds) when the server has not sent any messages and after which the server should
send a heartbeat frame to the client in order to keep the connection from breaking.
The default value is 25,000 (25 seconds). |
14 | The amount of time (in milliseconds) before a client is considered disconnected after not having a receiving connection (that is, an active connection over which the server can send data to the client).
The default value is 5000 . |
15 | The number of server-to-client messages that a session can cache while waiting for the next HTTP polling request from the client.
The default size is 100 . |
16 | Some load balancers do not support WebSockets.
Set this option to false to disable the WebSocket transport on the server side.
The default value is true . |
17 | The TaskScheduler bean reference.
A new ThreadPoolTaskScheduler instance is created if no value is provided.
This scheduler instance is used for scheduling heart-beat messages. |
18 | The SockJsMessageCodec bean reference to use for encoding and decoding SockJS messages.
By default, Jackson2SockJsMessageCodec is used, which requires the Jackson library to be present on the classpath. |
19 | List of TransportHandler bean references. |
20 | Whether to disable automatic addition of CORS headers for SockJS requests.
The default value is false . |
<int-websocket:outbound-channel-adapter>
Attributes
以下清单展示了 <int-websocket:outbound-channel-adapter>
元素可用的属性:
The following listing shows the attributes available for the <int-websocket:outbound-channel-adapter>
element:
<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 | The component bean name.
If you do not provide the channel attribute, a DirectChannel is created and registered in the application context with this id attribute as the bean name.
In this case, the endpoint is registered with the bean name id plus .adapter .
And the MessageHandler is registered with the bean alias id plus .handler . |
2 | Identifies the channel attached to this adapter. |
3 | The reference to the IntegrationWebSocketContainer bean, which encapsulates the low-level connection and WebSocketSession handling operations.
Required. |
4 | Optional reference to a SubProtocolHandler instance.
It is used when the client did not request a sub-protocol or it is a single protocol-handler.
If this reference or a protocol-handlers list is not provided, the PassThruSubProtocolHandler is used by default. |
5 | List of SubProtocolHandler bean references for this channel adapter.
If you provide only a single bean reference and do not provide a default-protocol-handler , that single SubProtocolHandler is used as the default-protocol-handler .
If you do not set this attribute or default-protocol-handler , the PassThruSubProtocolHandler is used by default. |
6 | List of MessageConverter bean references for this channel adapter. |
7 | Boolean value indicating whether the default converters should be registered after any custom converters.
This flag is used only if message-converters is provided.
Otherwise, all default converters are registered.
Defaults to false .
The default converters are (in order): StringMessageConverter , ByteArrayMessageConverter , and MappingJackson2MessageConverter (if the Jackson library is present on the classpath). |
8 | Boolean value indicating whether this endpoint should start automatically.
Defaults to true . |
9 | The lifecycle phase within which this endpoint should start and stop.
The lower the value, the earlier this endpoint starts and the later it stops.
The default is Integer.MIN_VALUE .
Values can be negative.
See SmartLifeCycle . |
<int-websocket:inbound-channel-adapter>
Attributes
以下清单展示了 <int-websocket:outbound-channel-adapter>
元素可用的属性:
The following listing shows the attributes available for the <int-websocket:outbound-channel-adapter>
element:
<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 | The component bean name.
If you do not set the channel attribute, a DirectChannel is created and registered in the application context with this id attribute as the bean name.
In this case, the endpoint is registered with the bean name id plus .adapter . |
2 | Identifies the channel attached to this adapter. |
3 | The MessageChannel bean reference to which the ErrorMessage instances should be sent. |
4 | See the same option on the <<`<int-websocket:outbound-channel-adapter>`,websocket-outbound-channel-adapter-attributes>>. |
5 | See the same option on the <<`<int-websocket:outbound-channel-adapter>`,websocket-outbound-channel-adapter-attributes>>. |
6 | See the same option on the <<`<int-websocket:outbound-channel-adapter>`,websocket-outbound-channel-adapter-attributes>>. |
7 | See the same option on the <<`<int-websocket:outbound-channel-adapter>`,websocket-outbound-channel-adapter-attributes>>. |
8 | See the same option on the <<`<int-websocket:outbound-channel-adapter>`,websocket-outbound-channel-adapter-attributes>>. |
9 | Maximum amount of time (in milliseconds) to wait when sending a message to the channel if the channel can block.
For example, a QueueChannel can block until space is available if its maximum capacity has been reached. |
10 | Fully qualified name of the Java type for the target payload to convert from the incoming WebSocketMessage .
Defaults to java.lang.String . |
11 | Indicates whether this adapter sends non-MESSAGE WebSocketMessage instances and messages with broker destinations to the AbstractBrokerMessageHandler from the application context.
When this attribute is true , the Broker Relay configuration is required.
This attribute is used only on the server side.
On the client side, it is ignored.
Defaults to false . |
12 | See the same option on the <<`<int-websocket:outbound-channel-adapter>`,websocket-outbound-channel-adapter-attributes>>. |
13 | See the same option on the <<`<int-websocket:outbound-channel-adapter>`,websocket-outbound-channel-adapter-attributes>>. |
Using ClientStompEncoder
从 4.3.13 版本开始,Spring Integration 提供 ClientStompEncoder
(作为标准 StompEncoder
的扩展)以供在 WebSocket 信道适配器的客户端使用。为了正确准备客户端消息,您必须将 ClientStompEncoder
的实例注入 StompSubProtocolHandler
。默认 StompSubProtocolHandler
的一个问题在于它是为服务器端设计的,因此它会将 SEND
stompCommand
标头更新为 MESSAGE
(这是服务器端 STOMP 协议的要求)。如果客户端不以正确的 SEND
Web 套接字框架发送其消息,则部分 STOMP 代理不会接受它们。在这种情况下,ClientStompEncoder
的目的是覆盖 stompCommand
标头,并将其设置为 SEND
值,然后再将消息编码为 byte[]
。
Starting with version 4.3.13, Spring Integration provides ClientStompEncoder
(as an extension of the standard StompEncoder
) for use on the client side of WebSocket channel adapters.
For proper client side message preparation, you must inject an instance of the ClientStompEncoder
into the StompSubProtocolHandler
.
One problem with the default StompSubProtocolHandler
is that it was designed for the server side, so it updates the SEND
stompCommand
header into MESSAGE
(as required by the STOMP protocol for the server side).
If the client does not send its messages in the proper SEND
web socket frame, some STOMP brokers do not accept them.
The purpose of the ClientStompEncoder
, in this case, is to override the stompCommand
header and set it to the SEND
value before encoding the message to the byte[]
.
Dynamic WebSocket Endpoints Registration
从 5.5 版本开始,WebSocket 服务器端点(基于 ServerWebSocketContainer
的信道适配器)现可在运行时注册(和移除) - 映射到 ServerWebSocketContainer
的 paths
通过 HandlerMapping
公开到 DispatcherServlet
中,并可供 WebSocket 客户端访问。Dynamic and Runtime Integration Flows 支持有助于以透明方式注册这些端点:
Starting with version 5.5, the WebSocket server endpoints (channel adapters based on a ServerWebSocketContainer
) can now be registered (and removed) at runtime - the paths
a ServerWebSocketContainer
is mapped is exposed via HandlerMapping
into a DispatcherServlet
and accessible for WebSocket clients.
The Dynamic and Runtime Integration Flows support helps to register these endpoints in a transparent manner:
@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();
在动态流注册中调用 |
It is important to call |
动态 WebSocket 端点只能通过 Spring Integration 机制注册:当使用常规 Spring @EnableWebsocket
时,Spring Integration 配置会退出,不会注册用于动态端点的任何基础结构。
The dynamic Websocket endpoints can only be registered via Spring Integration mechanism: when regular Spring @EnableWebsocket
is used, Spring Integration configuration backs off and no infrastructure for dynamic endpoints is registered.