INT-3611: Support WebSocketHandlerDecoratorFactory
JIRA: https://jira.spring.io/browse/INT-3611
This commit is contained in:
committed by
Gary Russell
parent
cd582926e1
commit
b57018b78b
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.websocket;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -20,10 +21,12 @@ import java.util.Arrays;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.config.annotation.SockJsServiceRegistration;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistration;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
||||
import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;
|
||||
import org.springframework.web.socket.server.HandshakeHandler;
|
||||
import org.springframework.web.socket.server.HandshakeInterceptor;
|
||||
import org.springframework.web.socket.sockjs.frame.SockJsMessageCodec;
|
||||
@@ -47,9 +50,11 @@ public class ServerWebSocketContainer extends IntegrationWebSocketContainer impl
|
||||
|
||||
private final String[] paths;
|
||||
|
||||
private volatile HandshakeHandler handshakeHandler;
|
||||
private HandshakeHandler handshakeHandler;
|
||||
|
||||
private volatile HandshakeInterceptor[] interceptors;
|
||||
private HandshakeInterceptor[] interceptors;
|
||||
|
||||
private WebSocketHandlerDecoratorFactory[] decoratorFactories;
|
||||
|
||||
private SockJsServiceOptions sockJsServiceOptions;
|
||||
|
||||
@@ -62,12 +67,30 @@ public class ServerWebSocketContainer extends IntegrationWebSocketContainer impl
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerWebSocketContainer setInterceptors(HandshakeInterceptor[] interceptors) {
|
||||
public ServerWebSocketContainer setInterceptors(HandshakeInterceptor... interceptors) {
|
||||
Assert.notNull(interceptors, "'interceptors' must not be null");
|
||||
Assert.noNullElements(interceptors, "'interceptors' must not contain null elements");
|
||||
this.interceptors = Arrays.copyOf(interceptors, interceptors.length);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure one or more factories to decorate the handler used to process
|
||||
* WebSocket messages. This may be useful in some advanced use cases, for
|
||||
* example to allow Spring Security to forcibly close the WebSocket session
|
||||
* when the corresponding HTTP session expires.
|
||||
* @param factories the WebSocketHandlerDecoratorFactory array to use
|
||||
* @return the current ServerWebSocketContainer
|
||||
* @since 4.2
|
||||
*/
|
||||
public ServerWebSocketContainer setDecoratorFactories(WebSocketHandlerDecoratorFactory... factories) {
|
||||
Assert.notNull(factories, "'factories' must not be null");
|
||||
Assert.noNullElements(factories, "'factories' must not contain null elements");
|
||||
this.decoratorFactories = Arrays.copyOf(factories, factories.length);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerWebSocketContainer withSockJs(SockJsServiceOptions... sockJsServiceOptions) {
|
||||
if (ObjectUtils.isEmpty(sockJsServiceOptions)) {
|
||||
this.sockJsServiceOptions = new SockJsServiceOptions();
|
||||
@@ -85,9 +108,18 @@ public class ServerWebSocketContainer extends IntegrationWebSocketContainer impl
|
||||
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
WebSocketHandlerRegistration registration = registry.addHandler(this.webSocketHandler, this.paths)
|
||||
WebSocketHandler webSocketHandler = this.webSocketHandler;
|
||||
|
||||
if (this.decoratorFactories != null) {
|
||||
for (WebSocketHandlerDecoratorFactory factory : this.decoratorFactories) {
|
||||
webSocketHandler = factory.decorate(webSocketHandler);
|
||||
}
|
||||
}
|
||||
|
||||
WebSocketHandlerRegistration registration = registry.addHandler(webSocketHandler, this.paths)
|
||||
.setHandshakeHandler(this.handshakeHandler)
|
||||
.addInterceptors(this.interceptors);
|
||||
|
||||
if (this.sockJsServiceOptions != null) {
|
||||
SockJsServiceRegistration sockJsServiceRegistration = registration.withSockJS();
|
||||
if (this.sockJsServiceOptions.webSocketEnabled != null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2015 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.
|
||||
@@ -62,6 +62,14 @@ public class ServerWebSocketContainerParser extends AbstractSingleBeanDefinition
|
||||
}
|
||||
builder.addPropertyValue("interceptors", handshakeInterceptorList);
|
||||
|
||||
String decoratorFactories = element.getAttribute("decorator-factories");
|
||||
List<BeanReference> decoratorFactoryList = new ManagedList<BeanReference>();
|
||||
ids = StringUtils.commaDelimitedListToStringArray(decoratorFactories);
|
||||
for (String id : ids) {
|
||||
decoratorFactoryList.add(new RuntimeBeanReference(id));
|
||||
}
|
||||
builder.addPropertyValue("decoratorFactories", decoratorFactoryList);
|
||||
|
||||
Element sockjs = DomUtils.getChildElementByTagName(element, "sockjs");
|
||||
|
||||
if (sockjs != null) {
|
||||
|
||||
@@ -280,6 +280,17 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="decorator-factories" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
List of 'org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory' bean references.
|
||||
Configure one or more factories to 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.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="send-time-limit" default="10000">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
||||
@@ -105,8 +105,6 @@ import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
|
||||
@DirtiesContext
|
||||
public class StompIntegrationTests {
|
||||
|
||||
private static final SpelExpressionParser PARSER = new SpelExpressionParser();
|
||||
|
||||
@Value("#{server.serverContext}")
|
||||
private ApplicationContext serverContext;
|
||||
|
||||
|
||||
@@ -18,16 +18,17 @@
|
||||
send-buffer-size-limit="100000"
|
||||
send-time-limit="100"
|
||||
handshake-handler="handshakeHandler"
|
||||
handshake-interceptors="handshakeInterceptor">
|
||||
handshake-interceptors="handshakeInterceptor"
|
||||
decorator-factories="decoratorFactory">
|
||||
<int-websocket:sockjs client-library-url="https://foo.sock.js"
|
||||
disconnect-delay="4000"
|
||||
heartbeat-time="30000"
|
||||
message-cache-size="10000"
|
||||
session-cookie-needed="false"
|
||||
stream-bytes-limit="2000"
|
||||
websocket-enabled="false"
|
||||
scheduler="taskScheduler"
|
||||
message-codec="sockJsMessageCodec"/>
|
||||
disconnect-delay="4000"
|
||||
heartbeat-time="30000"
|
||||
message-cache-size="10000"
|
||||
session-cookie-needed="false"
|
||||
stream-bytes-limit="2000"
|
||||
websocket-enabled="false"
|
||||
scheduler="taskScheduler"
|
||||
message-codec="sockJsMessageCodec"/>
|
||||
</int-websocket:server-container>
|
||||
|
||||
<bean id="handshakeHandler" class="org.mockito.Mockito" factory-method="mock">
|
||||
@@ -42,13 +43,16 @@
|
||||
<constructor-arg value="org.springframework.web.socket.sockjs.frame.SockJsMessageCodec"/>
|
||||
</bean>
|
||||
|
||||
<bean id="decoratorFactory"
|
||||
class="org.springframework.integration.websocket.config.WebSocketParserTests.TestWebSocketHandlerDecoratorFactory" />
|
||||
|
||||
<websocket:message-broker application-destination-prefix="/app">
|
||||
<websocket:stomp-endpoint path="/foo"/>
|
||||
<websocket:simple-broker prefix="/topic"/>
|
||||
</websocket:message-broker>
|
||||
|
||||
<int-websocket:inbound-channel-adapter id="defaultInboundAdapter" container="serverWebSocketContainer"
|
||||
use-broker="true"/>
|
||||
use-broker="true"/>
|
||||
|
||||
<bean id="webSocketClient" class="org.mockito.Mockito" factory-method="mock">
|
||||
<constructor-arg value="org.springframework.web.socket.client.WebSocketClient"/>
|
||||
@@ -93,11 +97,11 @@
|
||||
<int-websocket:outbound-channel-adapter id="defaultOutboundAdapter" container="serverWebSocketContainer"/>
|
||||
|
||||
<int-websocket:outbound-channel-adapter id="customOutboundAdapter" container="clientWebSocketContainer"
|
||||
default-protocol-handler="stompSubProtocolHandler"
|
||||
protocol-handlers="passThruSubProtocolHandler"
|
||||
message-converters="simpleMessageConverter,mapMessageConverter"
|
||||
merge-with-default-converters="true"
|
||||
channel="clientOutboundChannel"/>
|
||||
default-protocol-handler="stompSubProtocolHandler"
|
||||
protocol-handlers="passThruSubProtocolHandler"
|
||||
message-converters="simpleMessageConverter,mapMessageConverter"
|
||||
merge-with-default-converters="true"
|
||||
channel="clientOutboundChannel"/>
|
||||
|
||||
<int:channel id="clientOutboundChannel"/>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2015 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.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.integration.websocket.config;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -54,8 +55,10 @@ import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.WebSocketHttpHeaders;
|
||||
import org.springframework.web.socket.client.WebSocketClient;
|
||||
import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;
|
||||
import org.springframework.web.socket.messaging.StompSubProtocolHandler;
|
||||
import org.springframework.web.socket.server.HandshakeHandler;
|
||||
import org.springframework.web.socket.server.HandshakeInterceptor;
|
||||
@@ -138,7 +141,11 @@ public class WebSocketParserTests {
|
||||
@Qualifier("customOutboundAdapter.handler")
|
||||
private WebSocketOutboundMessageHandler customOutboundAdapter;
|
||||
|
||||
@Autowired
|
||||
private WebSocketHandlerDecoratorFactory decoratorFactory;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unckecked")
|
||||
public void testDefaultInboundChannelAdapterAndServerContainer() {
|
||||
Map<?, ?> urlMap = TestUtils.getPropertyValue(this.handlerMapping, "urlMap", Map.class);
|
||||
assertEquals(1, urlMap.size());
|
||||
@@ -152,11 +159,19 @@ public class WebSocketParserTests {
|
||||
TestUtils.getPropertyValue(this.serverWebSocketContainer, "handshakeHandler"));
|
||||
HandshakeInterceptor[] interceptors =
|
||||
TestUtils.getPropertyValue(this.serverWebSocketContainer, "interceptors", HandshakeInterceptor[].class);
|
||||
assertNotNull(interceptors);
|
||||
assertEquals(1, interceptors.length);
|
||||
assertSame(this.handshakeInterceptor, interceptors[0]);
|
||||
assertEquals(100, TestUtils.getPropertyValue(this.serverWebSocketContainer, "sendTimeLimit"));
|
||||
assertEquals(100000, TestUtils.getPropertyValue(this.serverWebSocketContainer, "sendBufferSizeLimit"));
|
||||
|
||||
WebSocketHandlerDecoratorFactory[] decoratorFactories =
|
||||
TestUtils.getPropertyValue(this.serverWebSocketContainer, "decoratorFactories",
|
||||
WebSocketHandlerDecoratorFactory[].class);
|
||||
assertNotNull(decoratorFactories);
|
||||
assertEquals(1, decoratorFactories.length);
|
||||
assertSame(this.decoratorFactory, decoratorFactories[0]);
|
||||
|
||||
TransportHandlingSockJsService sockJsService =
|
||||
TestUtils.getPropertyValue(mappedHandler, "sockJsService", TransportHandlingSockJsService.class);
|
||||
assertSame(this.taskScheduler, sockJsService.getTaskScheduler());
|
||||
@@ -298,4 +313,13 @@ public class WebSocketParserTests {
|
||||
assertTrue(TestUtils.getPropertyValue(this.customOutboundAdapter, "client", Boolean.class));
|
||||
}
|
||||
|
||||
private static class TestWebSocketHandlerDecoratorFactory implements WebSocketHandlerDecoratorFactory {
|
||||
|
||||
@Override
|
||||
public WebSocketHandler decorate(WebSocketHandler handler) {
|
||||
return handler;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,6 +37,11 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.PayloadApplicationEvent;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
@@ -46,6 +51,7 @@ import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.core.MessageProducer;
|
||||
import org.springframework.integration.event.inbound.ApplicationEventListeningMessageProducer;
|
||||
import org.springframework.integration.transformer.ExpressionEvaluatingTransformer;
|
||||
import org.springframework.integration.websocket.ClientWebSocketContainer;
|
||||
import org.springframework.integration.websocket.IntegrationWebSocketContainer;
|
||||
@@ -68,11 +74,16 @@ import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.WebSocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.client.WebSocketClient;
|
||||
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
|
||||
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
|
||||
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
|
||||
import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
|
||||
import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;
|
||||
import org.springframework.web.socket.messaging.StompSubProtocolHandler;
|
||||
import org.springframework.web.socket.messaging.SubProtocolHandler;
|
||||
import org.springframework.web.socket.sockjs.client.SockJsClient;
|
||||
@@ -101,6 +112,9 @@ public class WebSocketServerTests {
|
||||
@Value("#{server.serverContext.getBean('simpleBrokerMessageHandler')}")
|
||||
private SimpleBrokerMessageHandler brokerHandler;
|
||||
|
||||
@Value("#{server.serverContext.getBean('webSocketEvents')}")
|
||||
private PollableChannel webSocketEvents;
|
||||
|
||||
@Test
|
||||
public void testWebSocketOutboundMessageHandler() throws Exception {
|
||||
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.SUBSCRIBE);
|
||||
@@ -133,6 +147,10 @@ public class WebSocketServerTests {
|
||||
List<String> subscription = subscriptions.values().iterator().next();
|
||||
assertEquals(1, subscription.size());
|
||||
assertEquals("subs1", subscription.get(0));
|
||||
|
||||
Message<?> event = this.webSocketEvents.receive(10000);
|
||||
assertNotNull(event);
|
||||
assertThat(event.getPayload(), instanceOf(WebSocketSession.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -224,9 +242,16 @@ public class WebSocketServerTests {
|
||||
.enableSimpleBroker("/queue/", "/topic/");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebSocketHandlerDecoratorFactory testWebSocketHandlerDecoratorFactory() {
|
||||
return new TestWebSocketHandlerDecoratorFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServerWebSocketContainer serverWebSocketContainer() {
|
||||
return new ServerWebSocketContainer("/ws").withSockJs();
|
||||
return new ServerWebSocketContainer("/ws")
|
||||
.setDecoratorFactories(testWebSocketHandlerDecoratorFactory())
|
||||
.withSockJs();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -267,6 +292,57 @@ public class WebSocketServerTests {
|
||||
new SubProtocolHandlerRegistry(stompSubProtocolHandler()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PollableChannel webSocketEvents() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("unchecked")
|
||||
public ApplicationListener<ApplicationEvent> webSocketEventListener() {
|
||||
ApplicationEventListeningMessageProducer producer = new ApplicationEventListeningMessageProducer();
|
||||
producer.setEventTypes(PayloadApplicationEvent.class);
|
||||
producer.setExpressionPayload(new SpelExpressionParser().parseExpression("payload"));
|
||||
producer.setOutputChannel(webSocketEvents());
|
||||
return producer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TestWebSocketHandlerDecoratorFactory
|
||||
implements WebSocketHandlerDecoratorFactory, ApplicationEventPublisherAware {
|
||||
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
@Override
|
||||
public WebSocketHandler decorate(WebSocketHandler handler) {
|
||||
return new TestWebSocketHandler(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
this.applicationEventPublisher = applicationEventPublisher;
|
||||
}
|
||||
|
||||
private class TestWebSocketHandler extends WebSocketHandlerDecorator {
|
||||
|
||||
public TestWebSocketHandler(WebSocketHandler delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
|
||||
super.handleMessage(session, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
super.afterConnectionEstablished(session);
|
||||
applicationEventPublisher.publishEvent(session);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ It is based on architecture, infrastructure and API from the Spring Framework's
|
||||
Therefore, many of Spring WebSocket's components (e.g.
|
||||
`SubProtocolHandler` or `WebSocketClient`) and configuration options (e.g.
|
||||
`@EnableWebSocketMessageBroker`) can be reused within Spring Integration.
|
||||
For more information, please, refer to thehttp://docs.spring.io/spring/docs/current/spring-framework-reference/html/#websocket[Spring Framework WebSocket Support] chapter in the Spring Framework reference manual.
|
||||
For more information, please, refer to the http://docs.spring.io/spring/docs/current/spring-framework-reference/html/#websocket[Spring Framework WebSocket Support] chapter in the Spring Framework reference manual.
|
||||
|
||||
NOTE: Since the Spring Framework WebSocket infrastructure is based on the _Spring Messaging_ foundation and provides a basic Messaging framework based on the same `MessageChannel` s, `MessageHandler` 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 `@MessagingGateway` with appropriate annotations:
|
||||
@@ -195,19 +195,20 @@ See `SmartLifeCycle`.
|
||||
path="" <2>
|
||||
handshake-handler="" <3>
|
||||
handshake-interceptors="" <4>
|
||||
send-time-limit="" <5>
|
||||
send-buffer-size-limit=""> <6>
|
||||
decorator-factories="" <5>
|
||||
send-time-limit="" <6>
|
||||
send-buffer-size-limit=""> <7>
|
||||
<int-websocket:sockjs
|
||||
client-library-url="" <7>
|
||||
stream-bytes-limit="" <8>
|
||||
session-cookie-needed="" <9>
|
||||
heartbeat-time="" <10>
|
||||
disconnect-delay="" <11>
|
||||
message-cache-size="" <12>
|
||||
websocket-enabled="" <13>
|
||||
scheduler="" <14>
|
||||
message-codec="" <15>
|
||||
transport-handlers="" /> <16>
|
||||
client-library-url="" <8>
|
||||
stream-bytes-limit="" <9>
|
||||
session-cookie-needed="" <10>
|
||||
heartbeat-time="" <11>
|
||||
disconnect-delay="" <12>
|
||||
message-cache-size="" <13>
|
||||
websocket-enabled="" <14>
|
||||
scheduler="" <15>
|
||||
message-codec="" <16>
|
||||
transport-handlers="" /> <17>
|
||||
</int-websocket:server-container>
|
||||
----
|
||||
|
||||
@@ -225,13 +226,20 @@ Default to `DefaultHandshakeHandler`.
|
||||
<4> List of `HandshakeInterceptor` bean references.
|
||||
|
||||
|
||||
<5> See the same option on the `<int-websocket:client-container>`.
|
||||
|
||||
<5> Configure one or more factories (`WebSocketHandlerDecoratorFactory`) to 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 http://docs.spring.io/spring-session/docs/current/reference/html5/#websocket[Spring Session Project]
|
||||
for more information.
|
||||
|
||||
<6> See the same option on the `<int-websocket:client-container>`.
|
||||
|
||||
|
||||
<7> Transports with no native cross-domain communication (e.g.
|
||||
<7> See the same option on the `<int-websocket:client-container>`.
|
||||
|
||||
|
||||
<8> 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 `https://d1fxtkz8shb9d2.cloudfront.net/sockjs-0.3.4.min.js`.
|
||||
@@ -241,43 +249,47 @@ For example assuming a SockJS endpoint mapped to "/sockjs", and resulting iframe
|
||||
In case of a prefix-based Servlet mapping one more traversal may be needed.
|
||||
|
||||
|
||||
<8> Minimum number of bytes that can be send over a single HTTP streaming request before it will be closed.
|
||||
<9> Minimum number of bytes that can be send over a single HTTP streaming request before it will be closed.
|
||||
Defaults to `128K` (i.e.
|
||||
128*1024 bytes).
|
||||
|
||||
|
||||
<9> The "cookie_needed" value in the response from the SockJs `"/info"` endpoint.
|
||||
<10> The "cookie_needed" value in the response from the SockJs `"/info"` 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.
|
||||
|
||||
|
||||
<10> 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.
|
||||
<11> 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).
|
||||
|
||||
|
||||
<11> The amount of time in milliseconds before a client is considered disconnected after not having a receiving connection, i.e.
|
||||
<12> 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 `5000`.
|
||||
|
||||
|
||||
<12> The number of server-to-client messages that a session can cache while waiting for the next HTTP polling request from the client.
|
||||
<13> 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`.
|
||||
|
||||
|
||||
<13> Some load balancers don't support websockets.
|
||||
<14> Some load balancers don't support websockets.
|
||||
Set this option to `false` to disable the WebSocket transport on the server side.
|
||||
The default value is `true`.
|
||||
|
||||
|
||||
<14> The `TaskScheduler` bean reference; a new `ThreadPoolTaskScheduler` instance will be created if no value is provided.
|
||||
<15> The `TaskScheduler` bean reference; a new `ThreadPoolTaskScheduler` instance will be created if no value is
|
||||
provided.
|
||||
This scheduler instance will be used for scheduling heart-beat messages.
|
||||
|
||||
|
||||
<15> The `SockJsMessageCodec` bean reference to use for encoding and decoding SockJS messages.
|
||||
<16> The `SockJsMessageCodec` bean reference to use for encoding and decoding SockJS messages.
|
||||
By default `Jackson2SockJsMessageCodec` is used requiring the Jackson library to be present on the classpath.
|
||||
|
||||
|
||||
<16> List of `TransportHandler` bean references.
|
||||
<17> List of `TransportHandler` bean references.
|
||||
|
||||
*<int-websocket:outbound-channel-adapter>*
|
||||
|
||||
|
||||
@@ -260,3 +260,9 @@ When use FTP/SFTP outbound gateways to operate on multiple files (`mget`, `mput`
|
||||
occur after part of the request is completed.
|
||||
If such a condition occurs, a `PartialSuccessException` is thrown containing the partial results.
|
||||
See <<ftp-outbound-gateway>> and <<sftp-outbound-gateway>> for more information.
|
||||
|
||||
==== Websocket Changes
|
||||
|
||||
`WebSocketHandlerDecoratorFactory` support has been added to the `ServerWebSocketContainer`
|
||||
to allow chained customization for the internal `WebSocketHandler`.
|
||||
See <<web-sockets-namespace>> for more information.
|
||||
|
||||
Reference in New Issue
Block a user