INT-3511: Document WebSocket Support
JIRA: https://jira.spring.io/browse/INT-3511 Add note about Broker destinations Doc Polishing INT-3511: Fix 'useBroker' Docs and provide compatibility with SF 4.1.1
This commit is contained in:
committed by
Gary Russell
parent
1a0fdc6e53
commit
6814aafe48
@@ -26,9 +26,6 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
import org.springframework.web.socket.SubProtocolCapable;
|
||||
@@ -36,7 +33,6 @@ import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.WebSocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator;
|
||||
import org.springframework.web.socket.messaging.SessionDisconnectEvent;
|
||||
|
||||
/**
|
||||
* The high-level 'connection factory pattern' contract over low-level Web-Socket
|
||||
@@ -59,7 +55,7 @@ import org.springframework.web.socket.messaging.SessionDisconnectEvent;
|
||||
* @see org.springframework.integration.websocket.inbound.WebSocketInboundChannelAdapter
|
||||
* @see org.springframework.integration.websocket.outbound.WebSocketOutboundMessageHandler
|
||||
*/
|
||||
public abstract class IntegrationWebSocketContainer implements ApplicationEventPublisherAware, DisposableBean {
|
||||
public abstract class IntegrationWebSocketContainer implements DisposableBean {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
@@ -75,8 +71,6 @@ public abstract class IntegrationWebSocketContainer implements ApplicationEventP
|
||||
|
||||
private volatile int sendBufferSizeLimit = 512 * 1024;
|
||||
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public void setSendTimeLimit(int sendTimeLimit) {
|
||||
this.sendTimeLimit = sendTimeLimit;
|
||||
}
|
||||
@@ -85,11 +79,6 @@ public abstract class IntegrationWebSocketContainer implements ApplicationEventP
|
||||
this.sendBufferSizeLimit = sendBufferSizeLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
this.eventPublisher = applicationEventPublisher;
|
||||
}
|
||||
|
||||
public void setMessageListener(WebSocketListener messageListener) {
|
||||
Assert.state(this.messageListener == null || this.messageListener == messageListener,
|
||||
"'messageListener' is already configured");
|
||||
@@ -146,15 +135,6 @@ public abstract class IntegrationWebSocketContainer implements ApplicationEventP
|
||||
this.sessions.clear();
|
||||
}
|
||||
|
||||
private void publishEvent(ApplicationEvent event) {
|
||||
try {
|
||||
this.eventPublisher.publishEvent(event);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
logger.error("Error while publishing " + event, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal {@link WebSocketHandler} implementation to be used with native
|
||||
* Web-Socket containers.
|
||||
@@ -192,9 +172,6 @@ public abstract class IntegrationWebSocketContainer implements ApplicationEventP
|
||||
if (IntegrationWebSocketContainer.this.messageListener != null) {
|
||||
IntegrationWebSocketContainer.this.messageListener.afterSessionEnded(session, closeStatus);
|
||||
}
|
||||
else if (IntegrationWebSocketContainer.this.eventPublisher != null) {
|
||||
publishEvent(new SessionDisconnectEvent(this, session.getId(), closeStatus));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,10 +180,8 @@ public abstract class IntegrationWebSocketContainer implements ApplicationEventP
|
||||
WebSocketSession removed = IntegrationWebSocketContainer.this.sessions.remove(session.getId());
|
||||
if (removed != null) {
|
||||
IntegrationWebSocketContainer.this.sessions.remove(session.getId());
|
||||
if (IntegrationWebSocketContainer.this.eventPublisher != null) {
|
||||
publishEvent(new SessionErrorEvent(this, session.getId(), exception));
|
||||
}
|
||||
}
|
||||
throw new Exception(exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.websocket;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* The {@link ApplicationEvent} implementation to represent the
|
||||
* {@link org.springframework.web.socket.WebSocketSession} errors.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @since 4.1
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class SessionErrorEvent extends ApplicationEvent {
|
||||
|
||||
private final String sessionId;
|
||||
|
||||
private final Throwable exception;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@link ApplicationEvent} represented the error on the session.
|
||||
* @param source the component that published the event (never {@code null})
|
||||
* @param sessionId the id of the session
|
||||
* @param exception the exception on the session
|
||||
*/
|
||||
public SessionErrorEvent(Object source, String sessionId, Throwable exception) {
|
||||
super(source);
|
||||
Assert.notNull(sessionId, "'sessionId' must not be null");
|
||||
this.sessionId = sessionId;
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the session id.
|
||||
* @return the sessionId
|
||||
*/
|
||||
public String getSessionId() {
|
||||
return this.sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the exception for the session id.
|
||||
* @return the exception
|
||||
*/
|
||||
public Throwable getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SessionErrorEvent: sessionId=" + this.sessionId;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -234,7 +234,8 @@
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.web.socket.sockjs.frame.SockJsMessageCodec"/>
|
||||
<tool:expected-type
|
||||
type="org.springframework.web.socket.sockjs.frame.SockJsMessageCodec"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -357,7 +358,7 @@
|
||||
<xsd:attribute name="payload-type" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:java.lang.Class">
|
||||
Fully qualified name of the java type for the target `payload`
|
||||
Fully qualified name of the java type for the target 'payload'
|
||||
to convert from the incoming WebSocketMessage.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
@@ -365,11 +366,10 @@
|
||||
<xsd:attribute name="use-broker" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Flag to indicate if this adapter will send non-MESSAGE type WebSocketMessages
|
||||
and messages with broker destinations to the `AbstractBrokerMessageHandler`
|
||||
Flag to indicate if this adapter will send non-MESSAGE type 'WebSocketMessage's
|
||||
and messages with broker destinations to the 'AbstractBrokerMessageHandler'
|
||||
from the application context.
|
||||
If the `AbstractBrokerMessageHandler` bean isn't present the warn log is emitted
|
||||
and adapter behaviour is falling back to default like this attribute is 'false'.
|
||||
The 'Broker Relay' configuration is required when 'use-broker' is 'true'.
|
||||
This attribute is used only on server side. On client side it is ignored.
|
||||
Defaults to 'false'.
|
||||
</xsd:documentation>
|
||||
@@ -441,7 +441,7 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Flag to indicate if the default converters should be registered after any custom
|
||||
converters. This flag is used only if message-converters
|
||||
converters. This flag is used only if 'message-converters'
|
||||
are provided, otherwise all default converters will be registered.
|
||||
Defaults to 'false'.
|
||||
</xsd:documentation>
|
||||
|
||||
@@ -882,8 +882,7 @@ then you should simply provide an implementation of the <classname>ReleaseStrate
|
||||
</section>
|
||||
|
||||
<section id="reaper">
|
||||
<title id="reaper">Managing State in an Aggregator:
|
||||
MessageGroupStore</title>
|
||||
<title>Managing State in an Aggregator: MessageGroupStore</title>
|
||||
|
||||
<para>Aggregator (and some other patterns in Spring Integration) is a
|
||||
stateful pattern that requires decisions to be made based on a group of
|
||||
|
||||
@@ -144,6 +144,7 @@
|
||||
<xi:include href="./syslog.xml"/>
|
||||
<xi:include href="./ip.xml"/>
|
||||
<xi:include href="./twitter.xml"/>
|
||||
<xi:include href="./web-sockets.xml"/>
|
||||
<xi:include href="./ws.xml"/>
|
||||
<xi:include href="./xml.xml"/>
|
||||
<xi:include href="./xmpp.xml"/>
|
||||
|
||||
615
src/reference/docbook/web-sockets.xml
Normal file
615
src/reference/docbook/web-sockets.xml
Normal file
@@ -0,0 +1,615 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="web-sockets">
|
||||
<title>WebSockets Support</title>
|
||||
|
||||
<section id="web-socket-introduction">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
Starting with <emphasis>version 4.1</emphasis> Spring Integration has introduced
|
||||
<emphasis>WebSocket</emphasis> support. It is based on architecture, infrastructure and API
|
||||
from the Spring Framework's <emphasis>web-socket</emphasis> module. Therefore, many of Spring WebSocket's
|
||||
components (e.g. <interfacename>SubProtocolHandler</interfacename> or
|
||||
<interfacename>WebSocketClient</interfacename>) and configuration options (e.g.
|
||||
<interfacename>@EnableWebSocketMessageBroker</interfacename>) can be reused within Spring Integration.
|
||||
For more information, please, refer to the
|
||||
<ulink url="http://docs.spring.io/spring/docs/current/spring-framework-reference/html/#websocket"
|
||||
>Spring Framework WebSocket Support</ulink> chapter in the Spring Framework reference manual.
|
||||
</para>
|
||||
<note>
|
||||
Since the Spring Framework WebSocket infrastructure is based on the <emphasis>Spring Messaging</emphasis>
|
||||
foundation and provides a basic Messaging framework based on the same
|
||||
<interfacename>MessageChannel</interfacename>s, <interfacename>MessageHandler</interfacename>s
|
||||
that Spring Integration uses,
|
||||
and some POJO-method annotation mappings, Spring Integration can be directly involved in a
|
||||
WebSocket flow, even without WebSocket adapters. For this purpose you can simply configure a
|
||||
Spring Integration <interfacename>@MessagingGateway</interfacename> with appropriate annotations:
|
||||
</note>
|
||||
<programlisting language="java"><![CDATA[@MessagingGateway
|
||||
@Controller
|
||||
public interface WebSocketGateway {
|
||||
|
||||
@MessageMapping("/greeting")
|
||||
@SendToUser("/queue/answer")
|
||||
@Gateway(requestChannel = "greetingChannel")
|
||||
String greeting(String payload);
|
||||
|
||||
}]]></programlisting>
|
||||
</section>
|
||||
|
||||
<section id="web-socket-overview">
|
||||
<title>Overview</title>
|
||||
<para>
|
||||
Since the WebSocket protocol is <emphasis>streaming</emphasis> by definition and we can
|
||||
<emphasis>send</emphasis> and <emphasis>receive</emphasis> messages to/from a WebSocket at the same time,
|
||||
we can simply deal with an appropriate <interfacename>WebSocketSession</interfacename>,
|
||||
regardless of being on the client or server side. To encapsulate the connection management and
|
||||
<interfacename>WebSocketSession</interfacename> registry, the <classname>IntegrationWebSocketContainer</classname>
|
||||
is provided with <classname>ClientWebSocketContainer</classname> and <classname>ServerWebSocketContainer</classname>
|
||||
implementations. Thanks to the <ulink url="https://www.jcp.org/en/jsr/detail?id=356">WebSocket API</ulink>
|
||||
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). Hence most connection and
|
||||
<interfacename>WebSocketSession</interfacename> registry options are the same on both sides. That allows us
|
||||
to reuse many configuration items and infrastructure hooks to build WebSocket applications on the server
|
||||
side as well as on the client side:
|
||||
<programlisting language="java"><![CDATA[//Client side
|
||||
@Bean
|
||||
public WebSocketClient webSocketClient() {
|
||||
return new SockJsClient(Collections.<Transport>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();
|
||||
}]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The <classname>IntegrationWebSocketContainer</classname> is designed to achieve
|
||||
<emphasis>bidirectional</emphasis> messaging and can be shared between Inbound and Outbound
|
||||
Channel Adapters (see below), can be referenced only from one of them (when using
|
||||
one-way - sending or receiving - WebSocket messaging). It can be used without any Channel
|
||||
Adapter, but in this case, <classname>IntegrationWebSocketContainer</classname> only plays a role
|
||||
as the <interfacename>WebSocketSession</interfacename> registry.
|
||||
</para>
|
||||
<note>
|
||||
The <classname>ServerWebSocketContainer</classname> implements <interfacename>WebSocketConfigurer</interfacename>
|
||||
to register an internal <classname>IntegrationWebSocketContainer.IntegrationWebSocketHandler</classname>
|
||||
as an <code>Endpoint</code> under the provided <code>paths</code> and other server WebSocket options (such as
|
||||
<interfacename>HandshakeHandler</interfacename> or <code>SockJS fallback</code>) within the
|
||||
<classname>ServletWebSocketHandlerRegistry</classname> for the target vendor WebSocket Container. This
|
||||
registration is achieved with an infrastructural <classname>WebSocketIntegrationConfigurationInitializer</classname>
|
||||
component, which does the same as the <interfacename>@EnableWebSocket</interfacename> annotation. This means that
|
||||
using just <interfacename>@EnableIntegration</interfacename> (or any Spring Integration Namespace in the
|
||||
application context)
|
||||
you can omit the <interfacename>@EnableWebSocket</interfacename> declaration, because all WebSocket
|
||||
Endpoints are detected by the Spring Integration infrastructure.
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section id="web-socket-inbound-adapter">
|
||||
<title>WebSocket Inbound Channel Adapter</title>
|
||||
<para>
|
||||
The <classname>WebSocketInboundChannelAdapter</classname> implements the receiving part of
|
||||
<interfacename>WebSocketSession</interfacename> interaction. It must be supplied with a
|
||||
<classname>IntegrationWebSocketContainer</classname>, and the adapter registers itself as a
|
||||
<interfacename>WebSocketListener</interfacename> to handle incoming messages and
|
||||
<interfacename>WebSocketSession</interfacename> events.
|
||||
</para>
|
||||
<note>
|
||||
Only one <interfacename>WebSocketListener</interfacename> can be registered in the
|
||||
<classname>IntegrationWebSocketContainer</classname>.
|
||||
</note>
|
||||
<para>
|
||||
For WebSocket <emphasis>sub-protocol</emphasis>s, the
|
||||
<classname>WebSocketInboundChannelAdapter</classname> can be configured with
|
||||
<classname>SubProtocolHandlerRegistry</classname> as the second constructor argument. The adapter delegates
|
||||
to the <classname>SubProtocolHandlerRegistry</classname> to determine the appropriate
|
||||
<interfacename>SubProtocolHandler</interfacename> for the accepted <interfacename>WebSocketSession</interfacename>
|
||||
and to convert <interfacename>WebSocketMessage</interfacename> to a <interfacename>Message</interfacename>
|
||||
according to the sub-protocol implementation.
|
||||
</para>
|
||||
<note>
|
||||
By default, the <classname>WebSocketInboundChannelAdapter</classname> relies just only on the raw
|
||||
<classname>PassThruSubProtocolHandler</classname> implementation, which simply converts the
|
||||
<interfacename>WebSocketMessage</interfacename> to a <interfacename>Message</interfacename>.
|
||||
</note>
|
||||
<para>
|
||||
The <classname>WebSocketInboundChannelAdapter</classname> accepts and sends to the underlying integration
|
||||
flow only <interfacename>Message</interfacename>s with <code>SimpMessageType.MESSAGE</code> or an empty
|
||||
<code>simpMessageType</code> header. All other <interfacename>Message</interfacename> types are handled
|
||||
through the <interfacename>ApplicationEvent</interfacename>s emitted from a
|
||||
<interfacename>SubProtocolHandler</interfacename> implementation (e.g.
|
||||
<classname>StompSubProtocolHandler</classname>).
|
||||
</para>
|
||||
<para>
|
||||
On the server side <classname>WebSocketInboundChannelAdapter</classname> can be configured with the
|
||||
<code>useBroker = true</code> option, if the <interfacename>@EnableWebSocketMessageBroker</interfacename>
|
||||
configuration is present. In this case all <code>non-MESSAGE</code> <interfacename>Message</interfacename>
|
||||
types are delegated to the provided <classname>AbstractBrokerMessageHandler</classname>. In addition, if the
|
||||
Broker Relay is configured with destination prefixes, those Messages, which match to the Broker
|
||||
destinations, are routed to the <classname>AbstractBrokerMessageHandler</classname>, instead of to the
|
||||
<code>outputChannel</code> of the <classname>WebSocketInboundChannelAdapter</classname>.
|
||||
</para>
|
||||
<note>
|
||||
Spring's WebSocket Support allows the configuration of only one Broker Relay, hence we don't require an
|
||||
<classname>AbstractBrokerMessageHandler</classname> reference, it is detected in the
|
||||
Application Context.
|
||||
</note>
|
||||
<para>
|
||||
For more configuration option see <xref linkend="web-sockets-namespace"/>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="web-socket-outbound-adapter">
|
||||
<title>WebSocket Outbound Channel Adapter</title>
|
||||
<para>
|
||||
The <classname>WebSocketOutboundChannelAdapter</classname> accepts Spring Integration messages from its
|
||||
<interfacename>MessageChannel</interfacename>, determines the
|
||||
<interfacename>WebSocketSession</interfacename> <code>id</code> from the <classname>MessageHeaders</classname>,
|
||||
retrieves the <interfacename>WebSocketSession</interfacename> from the provided
|
||||
<classname>IntegrationWebSocketContainer</classname> and delegates the conversion and sending
|
||||
<interfacename>WebSocketMessage</interfacename> work to the appropriate
|
||||
<interfacename>SubProtocolHandler</interfacename> from the provided
|
||||
<classname>SubProtocolHandlerRegistry</classname>.
|
||||
</para>
|
||||
<para>
|
||||
On the client side, the <interfacename>WebSocketSession</interfacename> <code>id</code> message header isn't
|
||||
required, because <classname>ClientWebSocketContainer</classname> deals only with a single connection and
|
||||
its <interfacename>WebSocketSession</interfacename> respectively.
|
||||
</para>
|
||||
<para>
|
||||
To use the STOMP sub-protocol, this adapter should be configured with a
|
||||
<classname>StompSubProtocolHandler</classname>. Then you can send
|
||||
any STOMP message type to this adapter, using <code>StompHeaderAccessor.create(StompCommand...)</code> and
|
||||
a <classname>MessageBuilder</classname>, or just using a <code>HeaderEnricher</code> (see
|
||||
<xref linkend="header-enricher"/>).
|
||||
</para>
|
||||
<para>
|
||||
For more configuration option see below.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="web-sockets-namespace">
|
||||
<title>WebSockets Namespace Support</title>
|
||||
<para>
|
||||
Spring Integration <emphasis>WebSocket</emphasis> namespace includes several components described below.
|
||||
To include it in your configuration, simply provide the following namespace declaration in your
|
||||
application context configuration file:
|
||||
</para>
|
||||
|
||||
<programlisting language="xml"><![CDATA[<?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
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/websocket
|
||||
http://www.springframework.org/schema/integration/websocket/spring-integration-websocket.xsd">
|
||||
...
|
||||
</beans>]]></programlisting>
|
||||
<para>
|
||||
<emphasis role="bold"><int-websocket:client-container></emphasis>
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[<int-websocket:client-container
|
||||
id="" ]]><co id="ws-c-c-id" linkends="ws-c-c-id-l"/><![CDATA[
|
||||
client="" ]]><co id="ws-c-c-client" linkends="ws-c-c-client-l"/><![CDATA[
|
||||
uri="" ]]><co id="ws-c-c-uri" linkends="ws-c-c-uri-l"/><![CDATA[
|
||||
uri-variables="" ]]><co id="ws-c-c-uri-variables" linkends="ws-c-c-uri-variables-l"/><![CDATA[
|
||||
origin="" ]]><co id="ws-c-c-origin" linkends="ws-c-c-origin-l"/><![CDATA[
|
||||
send-time-limit="" ]]><co id="ws-c-c-send-time-limit" linkends="ws-c-c-send-time-limit-l"/><![CDATA[
|
||||
send-buffer-size-limit="" ]]><co id="ws-c-c-send-buffer" linkends="ws-c-c-send-buffer-l"/><![CDATA[
|
||||
auto-startup="" ]]><co id="ws-c-c-auto-startup" linkends="ws-c-c-auto-startup-l"/><![CDATA[
|
||||
phase=""> ]]><co id="ws-c-c-phase" linkends="ws-c-c-phase-l"/><![CDATA[
|
||||
<int-websocket:http-headers>
|
||||
<entry key="" value=""/>
|
||||
</int-websocket:http-headers> ]]><co id="ws-c-c-headers" linkends="ws-c-c-headers-l"/><![CDATA[
|
||||
</int-websocket:client-container>]]></programlisting>
|
||||
<para>
|
||||
<calloutlist>
|
||||
<callout arearefs="ws-c-c-id" id="ws-c-c-id-l">
|
||||
<para>
|
||||
The component bean name.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-c-c-client" id="ws-c-c-client-l">
|
||||
<para>
|
||||
The <interfacename>WebSocketClient</interfacename> bean reference.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-c-c-uri" id="ws-c-c-uri-l">
|
||||
<para>
|
||||
The <code>uri</code> or <code>uriTemplate</code> to the target WebSocket service. If it is used as
|
||||
a <code>uriTemplate</code> with URI variable placeholders, the <code>uri-variables</code>
|
||||
attribute is required.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-c-c-uri-variables" id="ws-c-c-uri-variables-l">
|
||||
<para>
|
||||
Comma-separated values for the URI variable placeholders within the <code>uri</code> attribute
|
||||
value. The values are replaced into the placeholders according
|
||||
to the order in the <code>uri</code>. See <code>UriComponents.expand(Object... uriVariableValues)</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-c-c-origin" id="ws-c-c-origin-l">
|
||||
<para>
|
||||
The <code>Origin</code> Handshake HTTP header value.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-c-c-send-time-limit" id="ws-c-c-send-time-limit-l">
|
||||
<para>
|
||||
The WebSocket session 'send' timeout limit. Defaults to <code>10000</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-c-c-send-buffer" id="ws-c-c-send-buffer-l">
|
||||
<para>
|
||||
The WebSocket session 'send' message size limit. Defaults to <code>524288</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-c-c-auto-startup" id="ws-c-c-auto-startup-l">
|
||||
<para>
|
||||
Boolean value indicating whether this endpoint should start automatically.
|
||||
Defaults to <code>false</code>, assuming that this container will be started from the
|
||||
<xref linkend="web-socket-inbound-adapter"/>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-c-c-phase" id="ws-c-c-phase-l">
|
||||
<para>
|
||||
The lifecycle phase within which this endpoint should start and stop.
|
||||
The lower the value the earlier this endpoint will start and the later it will stop. The
|
||||
default is <code>Integer.MAX_VALUE</code>. Values can be negative. See
|
||||
<interfacename>SmartLifeCycle</interfacename>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-c-c-headers" id="ws-c-c-headers-l">
|
||||
<para>
|
||||
A <interfacename>Map</interfacename> of <code>HttpHeaders</code> to be used with the
|
||||
Handshake request.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<emphasis role="bold"><int-websocket:server-container></emphasis>
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[<int-websocket:server-container
|
||||
id="" ]]><co id="ws-s-c-id" linkends="ws-s-c-id-l"/><![CDATA[
|
||||
path="" ]]><co id="ws-s-c-path" linkends="ws-s-c-path-l"/><![CDATA[
|
||||
handshake-handler="" ]]><co id="ws-s-c-handshake" linkends="ws-s-c-handshake-l"/><![CDATA[
|
||||
handshake-interceptors="" ]]><co id="ws-s-c-interceptors" linkends="ws-s-c-interceptors-l"/><![CDATA[
|
||||
send-time-limit="" ]]><co id="ws-s-c-time" linkends="ws-s-c-time-l"/><![CDATA[
|
||||
send-buffer-size-limit=""> ]]><co id="ws-s-c-buffer" linkends="ws-s-c-buffer-l"/><![CDATA[
|
||||
<int-websocket:sockjs
|
||||
client-library-url="" ]]><co id="ws-s-c-sockjs-url" linkends="ws-s-c-sockjs-url-l"/><![CDATA[
|
||||
stream-bytes-limit="" ]]><co id="ws-s-c-sockjs-stream" linkends="ws-s-c-sockjs-stream-l"/><![CDATA[
|
||||
session-cookie-needed="" ]]><co id="ws-s-c-sockjs-cookie" linkends="ws-s-c-sockjs-cookie-l"/><![CDATA[
|
||||
heartbeat-time="" ]]><co id="ws-s-c-sockjs-heartbeat" linkends="ws-s-c-sockjs-heartbeat-l"/><![CDATA[
|
||||
disconnect-delay="" ]]><co id="ws-s-c-sockjs-delay" linkends="ws-s-c-sockjs-delay-l"/><![CDATA[
|
||||
message-cache-size="" ]]><co id="ws-s-c-sockjs-cache" linkends="ws-s-c-sockjs-cache-l"/><![CDATA[
|
||||
websocket-enabled="" ]]><co id="ws-s-c-sockjs-websocket" linkends="ws-s-c-sockjs-websocket-l"/><![CDATA[
|
||||
scheduler="" ]]><co id="ws-s-c-sockjs-scheduler" linkends="ws-s-c-sockjs-scheduler-l"/><![CDATA[
|
||||
message-codec="" ]]><co id="ws-s-c-sockjs-codec" linkends="ws-s-c-sockjs-codec-l"/><![CDATA[
|
||||
transport-handlers="" /> ]]><co id="ws-s-c-sockjs-transport" linkends="ws-s-c-sockjs-transport-l"/><![CDATA[
|
||||
</int-websocket:server-container>]]></programlisting>
|
||||
<para>
|
||||
<calloutlist>
|
||||
<callout arearefs="ws-s-c-id" id="ws-s-c-id-l">
|
||||
<para>
|
||||
The component bean name.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-path" id="ws-s-c-path-l">
|
||||
<para>
|
||||
A path (or comma-separated paths) that maps a particular request to a
|
||||
<interfacename>WebSocketHandler</interfacename>.
|
||||
Exact path mapping URIs (such as <code>"/myPath"</code>) are supported as well
|
||||
as ant-style path patterns (such as <code>/myPath/**</code>).
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-handshake" id="ws-s-c-handshake-l">
|
||||
<para>
|
||||
The <interfacename>HandshakeHandler</interfacename> bean reference.
|
||||
Default to <classname>DefaultHandshakeHandler</classname>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-interceptors" id="ws-s-c-interceptors-l">
|
||||
<para>
|
||||
List of <interfacename>HandshakeInterceptor</interfacename> bean references.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-time" id="ws-s-c-time-l">
|
||||
<para>
|
||||
See the same option on the <code><int-websocket:client-container></code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-buffer" id="ws-s-c-buffer-l">
|
||||
<para>
|
||||
See the same option on the <code><int-websocket:client-container></code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-sockjs-url" id="ws-s-c-sockjs-url-l">
|
||||
<para>
|
||||
Transports with no native cross-domain communication (e.g. "eventsource",
|
||||
"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 allows specifying where to load it from.
|
||||
|
||||
By default this is set to point to
|
||||
<code>https://d1fxtkz8shb9d2.cloudfront.net/sockjs-0.3.4.min.js</code>. However it can
|
||||
also be set to point to a URL served by the application.
|
||||
|
||||
Note that it's 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 resulting iframe URL "/sockjs/iframe.html", then the
|
||||
The relative URL must start with "../../" to traverse up to the location
|
||||
above the SockJS mapping. In case of a prefix-based Servlet mapping one more
|
||||
traversal may be needed.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-sockjs-stream" id="ws-s-c-sockjs-stream-l">
|
||||
<para>
|
||||
Minimum number of bytes that can be send over a single HTTP streaming request before
|
||||
it will be closed. Defaults to <code>128K</code> (i.e. 128*1024 bytes).
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-sockjs-cookie" id="ws-s-c-sockjs-cookie-l">
|
||||
<para>
|
||||
The "cookie_needed" value in the response from the SockJs <code>"/info"</code> endpoint.
|
||||
This property indicates whether the use of a JSESSIONID cookie is required for the
|
||||
application to function correctly, e.g. for load balancing or in Java Servlet containers for
|
||||
the use of an HTTP session.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-sockjs-heartbeat" id="ws-s-c-sockjs-heartbeat-l">
|
||||
<para>
|
||||
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 <code>25,000</code> (25 seconds).
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-sockjs-delay" id="ws-s-c-sockjs-delay-l">
|
||||
<para>
|
||||
The amount of time in milliseconds before a client is considered disconnected after
|
||||
not having a receiving connection, i.e. an active connection over which the server can send
|
||||
data to the client. The default value is <code>5000</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-sockjs-cache" id="ws-s-c-sockjs-cache-l">
|
||||
<para>
|
||||
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 <code>100</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-sockjs-websocket" id="ws-s-c-sockjs-websocket-l">
|
||||
<para>
|
||||
Some load balancers don't support websockets. Set this option to <code>false</code> to disable
|
||||
the WebSocket transport on the server side. The default value is <code>true</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-sockjs-scheduler" id="ws-s-c-sockjs-scheduler-l">
|
||||
<para>
|
||||
The <interfacename>TaskScheduler</interfacename> bean reference; a new
|
||||
<classname>ThreadPoolTaskScheduler</classname> instance will be
|
||||
created if no value is provided. This scheduler instance will be used for scheduling
|
||||
heart-beat messages.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-sockjs-codec" id="ws-s-c-sockjs-codec-l">
|
||||
<para>
|
||||
The <interfacename>SockJsMessageCodec</interfacename> bean reference to use for
|
||||
encoding and decoding SockJS messages.
|
||||
By default <classname>Jackson2SockJsMessageCodec</classname> is used requiring the
|
||||
Jackson library to be present on the classpath.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-s-c-sockjs-transport" id="ws-s-c-sockjs-transport-l">
|
||||
<para>
|
||||
List of <interfacename>TransportHandler</interfacename> bean references.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<emphasis role="bold"><int-websocket:outbound-channel-adapter></emphasis>
|
||||
</para>
|
||||
<para>
|
||||
<programlisting language="xml"><![CDATA[<int-websocket:outbound-channel-adapter
|
||||
id="" ]]><co id="ws-o-a-id" linkends="ws-o-a-id-l"/><![CDATA[
|
||||
channel="" ]]><co id="ws-o-a-channel" linkends="ws-o-a-channel-l"/><![CDATA[
|
||||
container="" ]]><co id="ws-o-a-container" linkends="ws-o-a-container-l"/><![CDATA[
|
||||
default-protocol-handler="" ]]><co id="ws-o-a-handler" linkends="ws-o-a-handler-l"/><![CDATA[
|
||||
protocol-handlers="" ]]><co id="ws-o-a-handlers" linkends="ws-o-a-handlers-l"/><![CDATA[
|
||||
message-converters="" ]]><co id="ws-o-a-converters" linkends="ws-o-a-converters-l"/><![CDATA[
|
||||
merge-with-default-converters="" ]]><co id="ws-o-a-merge" linkends="ws-o-a-merge-l"/><![CDATA[
|
||||
auto-startup="" ]]><co id="ws-o-a-startup" linkends="ws-o-a-startup-l"/><![CDATA[
|
||||
phase=""/> ]]><co id="ws-o-a-phase" linkends="ws-o-a-phase-l"/></programlisting>
|
||||
<calloutlist>
|
||||
<callout arearefs="ws-o-a-id" id="ws-o-a-id-l">
|
||||
<para>
|
||||
The component bean name. If the <code>channel</code> attribute isn't provided, a
|
||||
<classname>DirectChannel</classname> is created and registered with the application context
|
||||
with this <code>id</code> attribute as the bean name. In this case, the endpoint is registered
|
||||
with the bean name <code>id + '.adapter'</code>. And the
|
||||
<interfacename>MessageHandler</interfacename> is registered with the bean alias
|
||||
<code>id +'.adapter'</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-o-a-channel" id="ws-o-a-channel-l">
|
||||
<para>
|
||||
Identifies the channel attached to this adapter.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-o-a-container" id="ws-o-a-container-l">
|
||||
<para>
|
||||
The reference to the <classname>IntegrationWebSocketContainer</classname> bean,
|
||||
which encapsulates the low-level connection and WebSocketSession handling operations. Required.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-o-a-handler" id="ws-o-a-handler-l">
|
||||
<para>
|
||||
Optional reference to a <interfacename>SubProtocolHandler</interfacename> instance.
|
||||
It is used when the client did not request a sub-protocol or it is a single protocol-handler.
|
||||
If this reference or <code>protocol-handlers</code> list aren't provided the
|
||||
<classname>PassThruSubProtocolHandler</classname> is used by default.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-o-a-handlers" id="ws-o-a-handlers-l">
|
||||
<para>
|
||||
List of <interfacename>SubProtocolHandler</interfacename> bean references
|
||||
for this Channel Adapter. If only a single bean reference is provided and a
|
||||
<code>default-protocol-handler</code> isn't provided, that single
|
||||
<interfacename>SubProtocolHandler</interfacename> will be used as the
|
||||
<code>default-protocol-handler</code>. If this attribute or
|
||||
<code>default-protocol-handler</code> aren't provided, the
|
||||
<classname>PassThruSubProtocolHandler</classname> is used by default.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-o-a-converters" id="ws-o-a-converters-l">
|
||||
<para>
|
||||
List of <interfacename>MessageConverter</interfacename> bean references for this Channel
|
||||
Adapter.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-o-a-merge" id="ws-o-a-merge-l">
|
||||
<para>
|
||||
Flag to indicate if the default converters should be registered after any custom
|
||||
converters. This flag is used only if <code>message-converters</code>
|
||||
are provided, otherwise all default converters will be registered.
|
||||
Defaults to <code>false</code>. The default converters are (in the order):
|
||||
<classname>StringMessageConverter</classname>, <classname>ByteArrayMessageConverter</classname>
|
||||
and <classname>MappingJackson2MessageConverter</classname> if the Jackson library is present on
|
||||
the classpath.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-o-a-startup" id="ws-o-a-startup-l">
|
||||
<para>
|
||||
Boolean value indicating whether this endpoint should start automatically.
|
||||
Default to <code>true</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-o-a-phase" id="ws-o-a-phase-l">
|
||||
<para>
|
||||
The lifecycle phase within which this endpoint should start and stop.
|
||||
The lower the value the earlier this endpoint will start and the later it will stop. The
|
||||
default is <code>Integer.MIN_VALUE</code>. Values can be negative.
|
||||
See <interfacename>SmartLifeCycle</interfacename>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<emphasis role="bold"><int-websocket:inbound-channel-adapter></emphasis>
|
||||
</para>
|
||||
<para>
|
||||
<programlisting language="xml"><![CDATA[<int-websocket:inbound-channel-adapter
|
||||
id="" ]]><co id="ws-i-a-id" linkends="ws-i-a-id-l"/><![CDATA[
|
||||
channel="" ]]><co id="ws-i-a-channel" linkends="ws-i-a-channel-l"/><![CDATA[
|
||||
error-channel="" ]]><co id="ws-i-a-error" linkends="ws-i-a-error-l"/><![CDATA[
|
||||
container="" ]]><co id="ws-i-a-container" linkends="ws-i-a-container-l"/><![CDATA[
|
||||
default-protocol-handler="" ]]><co id="ws-i-a-handler" linkends="ws-i-a-handler-l"/><![CDATA[
|
||||
protocol-handlers="" ]]><co id="ws-i-a-handlers" linkends="ws-i-a-handlers-l"/><![CDATA[
|
||||
message-converters="" ]]><co id="ws-i-a-converters" linkends="ws-i-a-converters-l"/><![CDATA[
|
||||
merge-with-default-converters="" ]]><co id="ws-i-a-merge" linkends="ws-i-a-merge-l"/><![CDATA[
|
||||
send-timeout="" ]]><co id="ws-i-a-timeout" linkends="ws-i-a-timeout-l"/><![CDATA[
|
||||
payload-type="" ]]><co id="ws-i-a-payload" linkends="ws-i-a-payload-l"/><![CDATA[
|
||||
use-broker="" ]]><co id="ws-i-a-broker" linkends="ws-i-a-broker-l"/><![CDATA[
|
||||
auto-startup="" ]]><co id="ws-i-a-startup" linkends="ws-i-a-startup-l"/><![CDATA[
|
||||
phase=""/> ]]><co id="ws-i-a-phase" linkends="ws-i-a-phase-l"/></programlisting>
|
||||
<calloutlist>
|
||||
<callout arearefs="ws-i-a-id" id="ws-i-a-id-l">
|
||||
<para>
|
||||
The component bean name. If the <code>channel</code> attribute isn't provided, a
|
||||
<classname>DirectChannel</classname> is created and registered with the application context
|
||||
with this <code>id</code> attribute as the bean name. In this case, the endpoint is registered
|
||||
with the bean name <code>id + '.adapter'</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-channel" id="ws-i-a-channel-l">
|
||||
<para>
|
||||
Identifies the channel attached to this adapter.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-error" id="ws-i-a-error-l">
|
||||
<para>
|
||||
The <interfacename>MessageChannel</interfacename> bean reference to which
|
||||
the <classname>ErrorMessages</classname> should be sent.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-container" id="ws-i-a-container-l">
|
||||
<para>
|
||||
See the same option on the <code><int-websocket:outbound-channel-adapter></code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-handler" id="ws-i-a-handler-l">
|
||||
<para>
|
||||
See the same option on the <code><int-websocket:outbound-channel-adapter></code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-handlers" id="ws-i-a-handlers-l">
|
||||
<para>
|
||||
See the same option on the <code><int-websocket:outbound-channel-adapter></code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-converters" id="ws-i-a-converters-l">
|
||||
<para>
|
||||
See the same option on the <code><int-websocket:outbound-channel-adapter></code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-merge" id="ws-i-a-merge-l">
|
||||
<para>
|
||||
See the same option on the <code><int-websocket:outbound-channel-adapter></code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-timeout" id="ws-i-a-timeout-l">
|
||||
<para>
|
||||
Maximum amount of time in milliseconds to wait when sending a message
|
||||
to the channel if the channel may block.
|
||||
For example, a <classname>QueueChannel</classname> can block until space is available
|
||||
if its maximum capacity has been reached.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-payload" id="ws-i-a-payload-l">
|
||||
<para>
|
||||
Fully qualified name of the java type for the target <classname>payload</classname>
|
||||
to convert from the incoming <interfacename>WebSocketMessage</interfacename>.
|
||||
Default to <classname>String</classname>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-broker" id="ws-i-a-broker-l">
|
||||
<para>
|
||||
Flag to indicate if this adapter will send <code>non-MESSAGE</code>
|
||||
<interfacename>WebSocketMessage</interfacename>s and messages with broker destinations to the
|
||||
<classname>AbstractBrokerMessageHandler</classname> from the application context.
|
||||
The <code>Broker Relay</code> configuration is required when this attribute is
|
||||
<code>true</code>.
|
||||
This attribute is used only on the server side. On the client side, it is ignored.
|
||||
Defaults to <code>false</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-startup" id="ws-i-a-startup-l">
|
||||
<para>
|
||||
See the same option on the <code><int-websocket:outbound-channel-adapter></code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="ws-i-a-phase" id="ws-i-a-phase-l">
|
||||
<para>
|
||||
See the same option on the <code><int-websocket:outbound-channel-adapter></code>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
@@ -18,13 +18,13 @@
|
||||
See <xref linkend="async-gateway"/>.
|
||||
</para>
|
||||
</section>
|
||||
<section id="4.1-web-sockets">
|
||||
<section id="4.1-web-socket-adapters">
|
||||
<title>WebSocket support</title>
|
||||
<para>
|
||||
The <emphasis>WebSocket</emphasis> module is now available. It is fully based on the Spring WebSocket
|
||||
and Spring Messaging modules and provides an <code><inbound-channel-adapter></code> and an
|
||||
<code><outbound-channel-adapter></code>.
|
||||
More documentation to follow.
|
||||
See <xref linkend="web-sockets"/> for more information.
|
||||
</para>
|
||||
</section>
|
||||
<section id="4.1-BoonJsonObjectMapper">
|
||||
|
||||
Reference in New Issue
Block a user