Add WebSocketClient and WebSocketConnectionManager
This change adds a WebSocketClient abstraction and enables the use of WebSocketHandler on the client side.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.springframework.websocket;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
@@ -32,14 +33,14 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class HandlerProvider<T> implements BeanFactoryAware {
|
||||
|
||||
private Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
private final T handlerBean;
|
||||
|
||||
private final Class<? extends T> handlerClass;
|
||||
|
||||
private AutowireCapableBeanFactory beanFactory;
|
||||
|
||||
private Log logger;
|
||||
|
||||
|
||||
public HandlerProvider(T handlerBean) {
|
||||
Assert.notNull(handlerBean, "handlerBean is required");
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.websocket;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class WebSocketHandshakeRequest {
|
||||
|
||||
private final URI uri;
|
||||
|
||||
private final HttpHeaders headers;
|
||||
|
||||
|
||||
public WebSocketHandshakeRequest(HttpHeaders headers, URI uri) {
|
||||
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public URI getUri() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
public HttpHeaders getHeaders() {
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* 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,
|
||||
@@ -13,17 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.websocket.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.DeploymentException;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
@@ -37,7 +30,7 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public abstract class AbstractEndpointConnectionManager implements SmartLifecycle {
|
||||
public abstract class AbstractWebSocketConnectionManager implements SmartLifecycle {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@@ -47,35 +40,15 @@ public abstract class AbstractEndpointConnectionManager implements SmartLifecycl
|
||||
|
||||
private int phase = Integer.MAX_VALUE;
|
||||
|
||||
private final WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer();
|
||||
|
||||
private Session session;
|
||||
|
||||
private TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("EndpointConnectionManager-");
|
||||
|
||||
private final Object lifecycleMonitor = new Object();
|
||||
|
||||
|
||||
public AbstractEndpointConnectionManager(String uriTemplate, Object... uriVariables) {
|
||||
public AbstractWebSocketConnectionManager(String uriTemplate, Object... uriVariables) {
|
||||
this.uri = UriComponentsBuilder.fromUriString(uriTemplate).buildAndExpand(uriVariables).encode().toUri();
|
||||
}
|
||||
|
||||
public void setAsyncSendTimeout(long timeoutInMillis) {
|
||||
this.webSocketContainer.setAsyncSendTimeout(timeoutInMillis);
|
||||
}
|
||||
|
||||
public void setMaxSessionIdleTimeout(long timeoutInMillis) {
|
||||
this.webSocketContainer.setDefaultMaxSessionIdleTimeout(timeoutInMillis);
|
||||
}
|
||||
|
||||
public void setMaxTextMessageBufferSize(int bufferSize) {
|
||||
this.webSocketContainer.setDefaultMaxTextMessageBufferSize(bufferSize);
|
||||
}
|
||||
|
||||
public void setMaxBinaryMessageBufferSize(Integer bufferSize) {
|
||||
this.webSocketContainer.setDefaultMaxBinaryMessageBufferSize(bufferSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to auto-connect to the remote endpoint after this connection manager
|
||||
* has been initialized and the Spring context has been refreshed.
|
||||
@@ -117,14 +90,11 @@ public abstract class AbstractEndpointConnectionManager implements SmartLifecycl
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
protected WebSocketContainer getWebSocketContainer() {
|
||||
return this.webSocketContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-connects to the configured {@link #setDefaultUri(URI) default URI}.
|
||||
* Connect to the configured {@link #setDefaultUri(URI) default URI}. If already
|
||||
* connected, the method has no impact.
|
||||
*/
|
||||
public void start() {
|
||||
public final void start() {
|
||||
synchronized (this.lifecycleMonitor) {
|
||||
if (!isRunning()) {
|
||||
this.taskExecutor.execute(new Runnable() {
|
||||
@@ -132,12 +102,12 @@ public abstract class AbstractEndpointConnectionManager implements SmartLifecycl
|
||||
public void run() {
|
||||
synchronized (lifecycleMonitor) {
|
||||
try {
|
||||
logger.info("Connecting to endpoint at URI " + uri);
|
||||
session = connect();
|
||||
logger.info("Connecting to WebSocket at " + uri);
|
||||
openConnection();
|
||||
logger.info("Successfully connected");
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
logger.error("Failed to connect to endpoint at " + uri, ex);
|
||||
logger.error("Failed to connect", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,25 +116,26 @@ public abstract class AbstractEndpointConnectionManager implements SmartLifecycl
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Session connect() throws DeploymentException, IOException;
|
||||
protected abstract void openConnection() throws Exception;
|
||||
|
||||
/**
|
||||
* Deactivates the configured message endpoint.
|
||||
* Closes the configured message WebSocket connection.
|
||||
*/
|
||||
public void stop() {
|
||||
public final void stop() {
|
||||
synchronized (this.lifecycleMonitor) {
|
||||
if (isRunning()) {
|
||||
try {
|
||||
this.session.close();
|
||||
closeConnection();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// ignore
|
||||
catch (Throwable e) {
|
||||
logger.error("Failed to stop WebSocket connection", e);
|
||||
}
|
||||
}
|
||||
this.session = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void closeConnection() throws Exception;
|
||||
|
||||
public void stop(Runnable callback) {
|
||||
synchronized (this.lifecycleMonitor) {
|
||||
this.stop();
|
||||
@@ -177,12 +148,10 @@ public abstract class AbstractEndpointConnectionManager implements SmartLifecycl
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
synchronized (this.lifecycleMonitor) {
|
||||
if ((this.session != null) && this.session.isOpen()) {
|
||||
return true;
|
||||
}
|
||||
this.session = null;
|
||||
return false;
|
||||
return isConnected();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean isConnected();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.websocket.client;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.websocket.WebSocketHandler;
|
||||
import org.springframework.websocket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* Contract for starting a WebSocket handshake request.
|
||||
*
|
||||
* <p>To automatically start a WebSocket connection when the application starts, see
|
||||
* {@link WebSocketConnectionManager}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*
|
||||
* @see WebSocketConnectionManager
|
||||
*/
|
||||
public interface WebSocketClient {
|
||||
|
||||
|
||||
WebSocketSession doHandshake(WebSocketHandler handler, String uriTemplate, Object... uriVariables)
|
||||
throws WebSocketConnectFailureException;
|
||||
|
||||
WebSocketSession doHandshake(WebSocketHandler handler, URI uri)
|
||||
throws WebSocketConnectFailureException;
|
||||
|
||||
WebSocketSession doHandshake(WebSocketHandler handler, HttpHeaders headers, URI uri)
|
||||
throws WebSocketConnectFailureException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.websocket.client;
|
||||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class WebSocketConnectFailureException extends NestedRuntimeException {
|
||||
|
||||
|
||||
public WebSocketConnectFailureException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
public WebSocketConnectFailureException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.websocket.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.websocket.HandlerProvider;
|
||||
import org.springframework.websocket.WebSocketHandler;
|
||||
import org.springframework.websocket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class WebSocketConnectionManager extends AbstractWebSocketConnectionManager {
|
||||
|
||||
private final WebSocketClient client;
|
||||
|
||||
private final HandlerProvider<WebSocketHandler> webSocketHandlerProvider;
|
||||
|
||||
private WebSocketSession webSocketSession;
|
||||
|
||||
private List<String> subProtocols;
|
||||
|
||||
|
||||
public WebSocketConnectionManager(WebSocketClient webSocketClient,
|
||||
WebSocketHandler webSocketHandler, String uriTemplate, Object... uriVariables) {
|
||||
|
||||
super(uriTemplate, uriVariables);
|
||||
this.webSocketHandlerProvider = new HandlerProvider<WebSocketHandler>(webSocketHandler);
|
||||
this.client = webSocketClient;
|
||||
}
|
||||
|
||||
public void setSubProtocols(List<String> subProtocols) {
|
||||
this.subProtocols = subProtocols;
|
||||
}
|
||||
|
||||
public List<String> getSubProtocols() {
|
||||
return this.subProtocols;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void openConnection() throws Exception {
|
||||
WebSocketHandler webSocketHandler = this.webSocketHandlerProvider.getHandler();
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setSecWebSocketProtocol(this.subProtocols);
|
||||
this.webSocketSession = this.client.doHandshake(webSocketHandler, headers, getUri());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeConnection() throws Exception {
|
||||
this.webSocketSession.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isConnected() {
|
||||
return ((this.webSocketSession != null) && (this.webSocketSession.isOpen()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,15 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.websocket.client;
|
||||
package org.springframework.websocket.client.endpoint;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.websocket.DeploymentException;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
@@ -34,24 +29,20 @@ import org.springframework.websocket.HandlerProvider;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class AnnotatedEndpointConnectionManager extends AbstractEndpointConnectionManager
|
||||
public class AnnotatedEndpointConnectionManager extends EndpointConnectionManagerSupport
|
||||
implements BeanFactoryAware {
|
||||
|
||||
private static Log logger = LogFactory.getLog(AnnotatedEndpointConnectionManager.class);
|
||||
|
||||
private final HandlerProvider<Object> endpointProvider;
|
||||
|
||||
|
||||
public AnnotatedEndpointConnectionManager(Class<?> endpointClass, String uriTemplate, Object... uriVariables) {
|
||||
super(uriTemplate, uriVariables);
|
||||
this.endpointProvider = new HandlerProvider<Object>(endpointClass);
|
||||
this.endpointProvider.setLogger(logger);
|
||||
}
|
||||
|
||||
public AnnotatedEndpointConnectionManager(Object endpointBean, String uriTemplate, Object... uriVariables) {
|
||||
super(uriTemplate, uriVariables);
|
||||
this.endpointProvider = new HandlerProvider<Object>(endpointBean);
|
||||
this.endpointProvider.setLogger(logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,10 +50,12 @@ public class AnnotatedEndpointConnectionManager extends AbstractEndpointConnecti
|
||||
this.endpointProvider.setBeanFactory(beanFactory);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Session connect() throws DeploymentException, IOException {
|
||||
protected void openConnection() throws Exception {
|
||||
Object endpoint = this.endpointProvider.getHandler();
|
||||
return getWebSocketContainer().connectToServer(endpoint, getUri());
|
||||
Session session = getWebSocketContainer().connectToServer(endpoint, getUri());
|
||||
updateSession(session);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,23 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.websocket.client;
|
||||
package org.springframework.websocket.client.endpoint;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.websocket.ClientEndpointConfig;
|
||||
import javax.websocket.ClientEndpointConfig.Configurator;
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.DeploymentException;
|
||||
import javax.websocket.Encoder;
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.Extension;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
@@ -43,27 +39,23 @@ import org.springframework.websocket.HandlerProvider;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class EndpointConnectionManager extends AbstractEndpointConnectionManager implements BeanFactoryAware {
|
||||
|
||||
private static Log logger = LogFactory.getLog(EndpointConnectionManager.class);
|
||||
public class EndpointConnectionManager extends EndpointConnectionManagerSupport implements BeanFactoryAware {
|
||||
|
||||
private final ClientEndpointConfig.Builder configBuilder = ClientEndpointConfig.Builder.create();
|
||||
|
||||
private final HandlerProvider<Endpoint> endpointProvider;
|
||||
|
||||
|
||||
public EndpointConnectionManager(Class<? extends Endpoint> endpointClass, String uriTemplate, Object... uriVariables) {
|
||||
super(uriTemplate, uriVariables);
|
||||
Assert.notNull(endpointClass, "endpointClass is required");
|
||||
this.endpointProvider = new HandlerProvider<Endpoint>(endpointClass);
|
||||
this.endpointProvider.setLogger(logger);
|
||||
}
|
||||
|
||||
public EndpointConnectionManager(Endpoint endpointBean, String uriTemplate, Object... uriVariables) {
|
||||
super(uriTemplate, uriVariables);
|
||||
Assert.notNull(endpointBean, "endpointBean is required");
|
||||
this.endpointProvider = new HandlerProvider<Endpoint>(endpointBean);
|
||||
this.endpointProvider.setLogger(logger);
|
||||
}
|
||||
|
||||
public EndpointConnectionManager(Class<? extends Endpoint> endpointClass, String uriTemplate, Object... uriVars) {
|
||||
super(uriTemplate, uriVars);
|
||||
Assert.notNull(endpointClass, "endpointClass is required");
|
||||
this.endpointProvider = new HandlerProvider<Endpoint>(endpointClass);
|
||||
}
|
||||
|
||||
public void setSubProtocols(String... subprotocols) {
|
||||
@@ -92,10 +84,11 @@ public class EndpointConnectionManager extends AbstractEndpointConnectionManager
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Session connect() throws DeploymentException, IOException {
|
||||
Endpoint typedEndpoint = this.endpointProvider.getHandler();
|
||||
protected void openConnection() throws Exception {
|
||||
Endpoint endpoint = this.endpointProvider.getHandler();
|
||||
ClientEndpointConfig endpointConfig = this.configBuilder.build();
|
||||
return getWebSocketContainer().connectToServer(typedEndpoint, endpointConfig, getUri());
|
||||
Session session = getWebSocketContainer().connectToServer(endpoint, endpointConfig, getUri());
|
||||
updateSession(session);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.websocket.client.endpoint;
|
||||
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
import org.springframework.websocket.client.AbstractWebSocketConnectionManager;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public abstract class EndpointConnectionManagerSupport extends AbstractWebSocketConnectionManager {
|
||||
|
||||
private WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer();
|
||||
|
||||
private Session session;
|
||||
|
||||
|
||||
public EndpointConnectionManagerSupport(String uriTemplate, Object... uriVariables) {
|
||||
super(uriTemplate, uriVariables);
|
||||
}
|
||||
|
||||
public void setWebSocketContainer(WebSocketContainer webSocketContainer) {
|
||||
this.webSocketContainer = webSocketContainer;
|
||||
}
|
||||
|
||||
public WebSocketContainer getWebSocketContainer() {
|
||||
return this.webSocketContainer;
|
||||
}
|
||||
|
||||
protected void updateSession(Session session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeConnection() throws Exception {
|
||||
try {
|
||||
if (isConnected()) {
|
||||
this.session.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
this.session = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isConnected() {
|
||||
return ((this.session != null) && this.session.isOpen());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.websocket.client.endpoint;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.websocket.ClientEndpointConfig;
|
||||
import javax.websocket.ClientEndpointConfig.Configurator;
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import org.springframework.websocket.WebSocketHandler;
|
||||
import org.springframework.websocket.WebSocketSession;
|
||||
import org.springframework.websocket.client.WebSocketClient;
|
||||
import org.springframework.websocket.client.WebSocketConnectFailureException;
|
||||
import org.springframework.websocket.endpoint.StandardWebSocketSession;
|
||||
import org.springframework.websocket.endpoint.WebSocketHandlerEndpoint;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class StandardWebSocketClient implements WebSocketClient {
|
||||
|
||||
private static final Set<String> EXCLUDED_HEADERS = new HashSet<String>(
|
||||
Arrays.asList("Sec-WebSocket-Accept", "Sec-WebSocket-Extensions", "Sec-WebSocket-Key",
|
||||
"Sec-WebSocket-Protocol", "Sec-WebSocket-Version"));
|
||||
|
||||
private WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer();
|
||||
|
||||
|
||||
public void setWebSocketContainer(WebSocketContainer container) {
|
||||
this.webSocketContainer = container;
|
||||
}
|
||||
|
||||
public WebSocketSession doHandshake(WebSocketHandler handler, String uriTemplate,
|
||||
Object... uriVariables) throws WebSocketConnectFailureException {
|
||||
|
||||
URI uri = UriComponentsBuilder.fromUriString(uriTemplate).buildAndExpand(uriVariables).encode().toUri();
|
||||
return doHandshake(handler, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketSession doHandshake(WebSocketHandler handler, URI uri) throws WebSocketConnectFailureException {
|
||||
return doHandshake(handler, null, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketSession doHandshake(WebSocketHandler handler, final HttpHeaders httpHeaders, URI uri)
|
||||
throws WebSocketConnectFailureException {
|
||||
|
||||
Endpoint endpoint = new WebSocketHandlerEndpoint(handler);
|
||||
|
||||
ClientEndpointConfig.Builder configBuidler = ClientEndpointConfig.Builder.create();
|
||||
if (httpHeaders != null) {
|
||||
List<String> protocols = httpHeaders.getSecWebSocketProtocol();
|
||||
if (!protocols.isEmpty()) {
|
||||
configBuidler.preferredSubprotocols(protocols);
|
||||
}
|
||||
configBuidler.configurator(new Configurator() {
|
||||
@Override
|
||||
public void beforeRequest(Map<String, List<String>> headers) {
|
||||
for (String headerName : httpHeaders.keySet()) {
|
||||
if (!EXCLUDED_HEADERS.contains(headerName)) {
|
||||
headers.put(headerName, httpHeaders.get(headerName));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
Session session = this.webSocketContainer.connectToServer(endpoint, configBuidler.build(), uri);
|
||||
return new StandardWebSocketSession(session);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new WebSocketConnectFailureException("Failed to connect to " + uri, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.websocket.client.endpoint;
|
||||
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
|
||||
/**
|
||||
* A FactoryBean for creating and configuring a {@link javax.websocket.WebSocketContainer}
|
||||
* through Spring XML configuration. In Java configuration, ignore this class and use
|
||||
* {@code ContainerProvider.getWebSocketContainer()} instead.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class WebSocketContainerFactoryBean implements FactoryBean<WebSocketContainer> {
|
||||
|
||||
private final WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer();
|
||||
|
||||
|
||||
public void setAsyncSendTimeout(long timeoutInMillis) {
|
||||
this.webSocketContainer.setAsyncSendTimeout(timeoutInMillis);
|
||||
}
|
||||
|
||||
public long getAsyncSendTimeout() {
|
||||
return this.webSocketContainer.getDefaultAsyncSendTimeout();
|
||||
}
|
||||
|
||||
public void setMaxSessionIdleTimeout(long timeoutInMillis) {
|
||||
this.webSocketContainer.setDefaultMaxSessionIdleTimeout(timeoutInMillis);
|
||||
}
|
||||
|
||||
public long getMaxSessionIdleTimeout() {
|
||||
return this.webSocketContainer.getDefaultMaxSessionIdleTimeout();
|
||||
}
|
||||
|
||||
public void setMaxTextMessageBufferSize(int bufferSize) {
|
||||
this.webSocketContainer.setDefaultMaxTextMessageBufferSize(bufferSize);
|
||||
}
|
||||
|
||||
public int getMaxTextMessageBufferSize() {
|
||||
return this.webSocketContainer.getDefaultMaxTextMessageBufferSize();
|
||||
}
|
||||
|
||||
public void setMaxBinaryMessageBufferSize(int bufferSize) {
|
||||
this.webSocketContainer.setDefaultMaxBinaryMessageBufferSize(bufferSize);
|
||||
}
|
||||
|
||||
public int getMaxBinaryMessageBufferSize() {
|
||||
return this.webSocketContainer.getDefaultMaxBinaryMessageBufferSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketContainer getObject() throws Exception {
|
||||
return this.webSocketContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return WebSocketContainer.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Client-side classes for use with standard Java WebSocket endpoints including
|
||||
* {@link org.springframework.websocket.client.endpoint.EndpointConnectionManager} and
|
||||
* {@link org.springframework.websocket.client.endpoint.AnnotatedEndpointConnectionManager}
|
||||
* for connecting to server endpoints using type-based or annotated endpoints respectively.
|
||||
*/
|
||||
package org.springframework.websocket.client.endpoint;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
/**
|
||||
* Client-side support for WebSocket applications.
|
||||
* Server-side abstractions for WebSocket applications.
|
||||
*
|
||||
*/
|
||||
package org.springframework.websocket.client;
|
||||
|
||||
@@ -54,8 +54,7 @@ public class WebSocketHandlerEndpoint extends Endpoint {
|
||||
@Override
|
||||
public void onOpen(javax.websocket.Session session, EndpointConfig config) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Client connected, WebSocket session id=" + session.getId()
|
||||
+ ", path=" + session.getRequestURI().getPath());
|
||||
logger.debug("Client connected, WebSocket session id=" + session.getId() + ", uri=" + session.getRequestURI());
|
||||
}
|
||||
try {
|
||||
WebSocketSession webSocketSession = new StandardWebSocketSession(session);
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
*/
|
||||
package org.springframework.websocket.server.endpoint;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.websocket.DeploymentException;
|
||||
@@ -25,13 +29,13 @@ import javax.websocket.server.ServerEndpointConfig;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* BeanPostProcessor that detects beans of type
|
||||
@@ -43,114 +47,79 @@ import org.springframework.util.ObjectUtils;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public abstract class EndpointExporter implements InitializingBean, BeanPostProcessor, BeanFactoryAware {
|
||||
public class EndpointExporter implements InitializingBean, BeanPostProcessor, ApplicationContextAware {
|
||||
|
||||
private static final boolean isServletApiPresent =
|
||||
ClassUtils.isPresent("javax.servlet.ServletContext", EndpointExporter.class.getClassLoader());
|
||||
|
||||
private static Log logger = LogFactory.getLog(EndpointExporter.class);
|
||||
|
||||
private Class<?>[] annotatedEndpointClasses;
|
||||
private final List<Class<?>> annotatedEndpointClasses = new ArrayList<Class<?>>();
|
||||
|
||||
private Long maxSessionIdleTimeout;
|
||||
private final List<Class<?>> annotatedEndpointBeanTypes = new ArrayList<Class<?>>();
|
||||
|
||||
private Integer maxTextMessageBufferSize;
|
||||
|
||||
private Integer maxBinaryMessageBufferSize;
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private ServerContainer serverContainer;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param annotatedEndpointClasses
|
||||
*/
|
||||
public void setAnnotatedEndpointClasses(Class<?>... annotatedEndpointClasses) {
|
||||
this.annotatedEndpointClasses = annotatedEndpointClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this property set it is in turn used to configure
|
||||
* {@link ServerContainer#setDefaultMaxSessionIdleTimeout(long)}.
|
||||
*/
|
||||
public void setMaxSessionIdleTimeout(long maxSessionIdleTimeout) {
|
||||
this.maxSessionIdleTimeout = maxSessionIdleTimeout;
|
||||
}
|
||||
|
||||
public Long getMaxSessionIdleTimeout() {
|
||||
return this.maxSessionIdleTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this property set it is in turn used to configure
|
||||
* {@link ServerContainer#setDefaultMaxTextMessageBufferSize(int)}
|
||||
*/
|
||||
public void setMaxTextMessageBufferSize(int maxTextMessageBufferSize) {
|
||||
this.maxTextMessageBufferSize = maxTextMessageBufferSize;
|
||||
}
|
||||
|
||||
public Integer getMaxTextMessageBufferSize() {
|
||||
return this.maxTextMessageBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this property set it is in turn used to configure
|
||||
* {@link ServerContainer#setDefaultMaxBinaryMessageBufferSize(int)}.
|
||||
*/
|
||||
public void setMaxBinaryMessageBufferSize(int maxBinaryMessageBufferSize) {
|
||||
this.maxBinaryMessageBufferSize = maxBinaryMessageBufferSize;
|
||||
}
|
||||
|
||||
public Integer getMaxBinaryMessageBufferSize() {
|
||||
return this.maxBinaryMessageBufferSize;
|
||||
this.annotatedEndpointClasses.clear();
|
||||
this.annotatedEndpointClasses.addAll(Arrays.asList(annotatedEndpointClasses));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
if (beanFactory instanceof ListableBeanFactory) {
|
||||
ListableBeanFactory lbf = (ListableBeanFactory) beanFactory;
|
||||
Map<String, Object> annotatedEndpoints = lbf.getBeansWithAnnotation(ServerEndpoint.class);
|
||||
for (String beanName : annotatedEndpoints.keySet()) {
|
||||
Class<?> beanType = lbf.getType(beanName);
|
||||
try {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Detected @ServerEndpoint bean '" + beanName + "', registering it as an endpoint by type");
|
||||
}
|
||||
getServerContainer().addEndpoint(beanType);
|
||||
}
|
||||
catch (DeploymentException e) {
|
||||
throw new IllegalStateException("Failed to register @ServerEndpoint bean type " + beanName, e);
|
||||
}
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
|
||||
this.applicationContext = applicationContext;
|
||||
|
||||
this.serverContainer = getServerContainer();
|
||||
|
||||
Map<String, Object> beans = applicationContext.getBeansWithAnnotation(ServerEndpoint.class);
|
||||
for (String beanName : beans.keySet()) {
|
||||
Class<?> beanType = applicationContext.getType(beanName);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Detected @ServerEndpoint bean '" + beanName + "', registering it as an endpoint by type");
|
||||
}
|
||||
this.annotatedEndpointBeanTypes.add(beanType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link ServerContainer} instance, a process which is undefined outside
|
||||
* of standalone containers (section 6.4 of the spec).
|
||||
*/
|
||||
protected abstract ServerContainer getServerContainer();
|
||||
protected ServerContainer getServerContainer() {
|
||||
if (isServletApiPresent) {
|
||||
try {
|
||||
Method getter = ReflectionUtils.findMethod(this.applicationContext.getClass(), "getServletContext");
|
||||
Object servletContext = getter.invoke(this.applicationContext);
|
||||
|
||||
Method attrMethod = ReflectionUtils.findMethod(servletContext.getClass(), "getAttribute", String.class);
|
||||
return (ServerContainer) attrMethod.invoke(servletContext, "javax.websocket.server.ServerContainer");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Failed to get javax.websocket.server.ServerContainer via ServletContext attribute", ex);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
ServerContainer serverContainer = getServerContainer();
|
||||
Assert.notNull(serverContainer, "javax.websocket.server.ServerContainer not available");
|
||||
|
||||
if (this.maxSessionIdleTimeout != null) {
|
||||
serverContainer.setDefaultMaxSessionIdleTimeout(this.maxSessionIdleTimeout);
|
||||
}
|
||||
if (this.maxTextMessageBufferSize != null) {
|
||||
serverContainer.setDefaultMaxTextMessageBufferSize(this.maxTextMessageBufferSize);
|
||||
}
|
||||
if (this.maxBinaryMessageBufferSize != null) {
|
||||
serverContainer.setDefaultMaxBinaryMessageBufferSize(this.maxBinaryMessageBufferSize);
|
||||
}
|
||||
List<Class<?>> allClasses = new ArrayList<Class<?>>(this.annotatedEndpointClasses);
|
||||
allClasses.addAll(this.annotatedEndpointBeanTypes);
|
||||
|
||||
if (!ObjectUtils.isEmpty(this.annotatedEndpointClasses)) {
|
||||
for (Class<?> clazz : this.annotatedEndpointClasses) {
|
||||
try {
|
||||
logger.info("Registering @ServerEndpoint type " + clazz);
|
||||
serverContainer.addEndpoint(clazz);
|
||||
}
|
||||
catch (DeploymentException e) {
|
||||
throw new IllegalStateException("Failed to register @ServerEndpoint type " + clazz, e);
|
||||
}
|
||||
for (Class<?> clazz : allClasses) {
|
||||
try {
|
||||
logger.info("Registering @ServerEndpoint type " + clazz);
|
||||
this.serverContainer.addEndpoint(clazz);
|
||||
}
|
||||
catch (DeploymentException e) {
|
||||
throw new IllegalStateException("Failed to register @ServerEndpoint type " + clazz, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.websocket.server.endpoint;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.websocket.server.ServerContainer;
|
||||
import javax.websocket.server.ServerContainerProvider;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
|
||||
|
||||
/**
|
||||
* A sub-class of {@link EndpointExporter} for use with a Servlet container runtime.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class ServletEndpointExporter extends EndpointExporter implements ServletContextAware {
|
||||
|
||||
private static final String SERVER_CONTAINER_ATTR_NAME = "javax.websocket.server.ServerContainer";
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
public ServletContext getServletContext() {
|
||||
return this.servletContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerContainer getServerContainer() {
|
||||
Assert.notNull(this.servletContext, "A ServletContext is needed to access the WebSocket ServerContainer");
|
||||
ServerContainer container = (ServerContainer) this.servletContext.getAttribute(SERVER_CONTAINER_ATTR_NAME);
|
||||
if (container == null) {
|
||||
// Remove when Tomcat has caught up to http://java.net/jira/browse/WEBSOCKET_SPEC-165
|
||||
return ServerContainerProvider.getServerContainer();
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.websocket.server.endpoint;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
import javax.websocket.server.ServerContainer;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.sockjs.server.SockJsService;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
import org.springframework.websocket.server.DefaultHandshakeHandler;
|
||||
|
||||
|
||||
/**
|
||||
* A FactoryBean for {@link javax.websocket.server.ServerContainer}. Since
|
||||
* there is only one {@code ServerContainer} instance accessible under a well-known
|
||||
* {@code javax.servlet.ServletContext} attribute, simply declaring this FactoryBean and
|
||||
* using its setters allows configuring the {@code ServerContainer} through Spring
|
||||
* configuration. This is useful even if the ServerContainer is not injected into any
|
||||
* other bean. For example, an application can configure a {@link DefaultHandshakeHandler}
|
||||
* , a {@link SockJsService}, or {@link EndpointExporter}, and separately declare this
|
||||
* FactoryBean in order to customize the properties of the (one and only)
|
||||
* {@code ServerContainer} instance.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class ServletServerContainerFactoryBean
|
||||
implements FactoryBean<WebSocketContainer>, InitializingBean, ServletContextAware {
|
||||
|
||||
private static final String SERVER_CONTAINER_ATTR_NAME = "javax.websocket.server.ServerContainer";
|
||||
|
||||
private Long asyncSendTimeout;
|
||||
|
||||
private Long maxSessionIdleTimeout;
|
||||
|
||||
private Integer maxTextMessageBufferSize;
|
||||
|
||||
private Integer maxBinaryMessageBufferSize;
|
||||
|
||||
|
||||
private ServerContainer serverContainer;
|
||||
|
||||
|
||||
public void setAsyncSendTimeout(long timeoutInMillis) {
|
||||
this.asyncSendTimeout = timeoutInMillis;
|
||||
}
|
||||
|
||||
public long getAsyncSendTimeout() {
|
||||
return this.asyncSendTimeout;
|
||||
}
|
||||
|
||||
public void setMaxSessionIdleTimeout(long timeoutInMillis) {
|
||||
this.maxSessionIdleTimeout = timeoutInMillis;
|
||||
}
|
||||
|
||||
public Long getMaxSessionIdleTimeout() {
|
||||
return this.maxSessionIdleTimeout;
|
||||
}
|
||||
|
||||
public void setMaxTextMessageBufferSize(int bufferSize) {
|
||||
this.maxTextMessageBufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public Integer getMaxTextMessageBufferSize() {
|
||||
return this.maxTextMessageBufferSize;
|
||||
}
|
||||
|
||||
public void setMaxBinaryMessageBufferSize(int bufferSize) {
|
||||
this.maxBinaryMessageBufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public Integer getMaxBinaryMessageBufferSize() {
|
||||
return this.maxBinaryMessageBufferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.serverContainer = (ServerContainer) servletContext.getAttribute(SERVER_CONTAINER_ATTR_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerContainer getObject() {
|
||||
return this.serverContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return ServerContainer.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
Assert.notNull(this.serverContainer,
|
||||
"A ServletContext is required to access the javax.websocket.server.ServerContainer instance");
|
||||
|
||||
if (this.asyncSendTimeout != null) {
|
||||
this.serverContainer.setAsyncSendTimeout(this.asyncSendTimeout);
|
||||
}
|
||||
if (this.maxSessionIdleTimeout != null) {
|
||||
this.serverContainer.setDefaultMaxSessionIdleTimeout(this.maxSessionIdleTimeout);
|
||||
}
|
||||
if (this.maxTextMessageBufferSize != null) {
|
||||
this.serverContainer.setDefaultMaxTextMessageBufferSize(this.maxTextMessageBufferSize);
|
||||
}
|
||||
if (this.maxBinaryMessageBufferSize != null) {
|
||||
this.serverContainer.setDefaultMaxBinaryMessageBufferSize(this.maxBinaryMessageBufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.websocket.server.support;
|
||||
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public abstract class AbstractEndpointContainerFactoryBean implements FactoryBean<WebSocketContainer>, InitializingBean {
|
||||
|
||||
private WebSocketContainer container;
|
||||
|
||||
|
||||
public void setAsyncSendTimeout(long timeoutInMillis) {
|
||||
this.container.setAsyncSendTimeout(timeoutInMillis);
|
||||
}
|
||||
|
||||
public long getAsyncSendTimeout() {
|
||||
return this.container.getDefaultAsyncSendTimeout();
|
||||
}
|
||||
|
||||
public void setMaxSessionIdleTimeout(long timeoutInMillis) {
|
||||
this.container.setDefaultMaxSessionIdleTimeout(timeoutInMillis);
|
||||
}
|
||||
|
||||
public long getMaxSessionIdleTimeout() {
|
||||
return this.container.getDefaultMaxSessionIdleTimeout();
|
||||
}
|
||||
|
||||
public void setMaxTextMessageBufferSize(int bufferSize) {
|
||||
this.container.setDefaultMaxTextMessageBufferSize(bufferSize);
|
||||
}
|
||||
|
||||
public int getMaxTextMessageBufferSize() {
|
||||
return this.container.getDefaultMaxTextMessageBufferSize();
|
||||
}
|
||||
|
||||
public void setMaxBinaryMessageBufferSize(int bufferSize) {
|
||||
this.container.setDefaultMaxBinaryMessageBufferSize(bufferSize);
|
||||
}
|
||||
|
||||
public int getMaxBinaryMessageBufferSize() {
|
||||
return this.container.getDefaultMaxBinaryMessageBufferSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.container = getContainer();
|
||||
}
|
||||
|
||||
protected abstract WebSocketContainer getContainer();
|
||||
|
||||
@Override
|
||||
public WebSocketContainer getObject() throws Exception {
|
||||
return this.container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return WebSocketContainer.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user