Polishing
This commit is contained in:
@@ -20,14 +20,15 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import reactor.fn.Consumer;
|
||||
import reactor.rx.Promise;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.concurrent.FailureCallback;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
import org.springframework.util.concurrent.ListenableFutureCallback;
|
||||
import org.springframework.util.concurrent.ListenableFutureCallbackRegistry;
|
||||
import org.springframework.util.concurrent.SuccessCallback;
|
||||
import reactor.fn.Consumer;
|
||||
import reactor.rx.Promise;
|
||||
|
||||
/**
|
||||
* Adapts a reactor {@link Promise} to {@link ListenableFuture} optionally converting
|
||||
@@ -55,21 +56,20 @@ abstract class AbstractPromiseToListenableFutureAdapter<S, T> implements Listena
|
||||
try {
|
||||
registry.success(adapt(result));
|
||||
}
|
||||
catch (Throwable t) {
|
||||
registry.failure(t);
|
||||
catch (Throwable ex) {
|
||||
registry.failure(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.promise.onError(new Consumer<Throwable>() {
|
||||
@Override
|
||||
public void accept(Throwable t) {
|
||||
registry.failure(t);
|
||||
public void accept(Throwable ex) {
|
||||
registry.failure(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract T adapt(S result);
|
||||
|
||||
@Override
|
||||
public T get() throws InterruptedException {
|
||||
@@ -112,4 +112,7 @@ abstract class AbstractPromiseToListenableFutureAdapter<S, T> implements Listena
|
||||
this.registry.addFailureCallback(failureCallback);
|
||||
}
|
||||
|
||||
|
||||
protected abstract T adapt(S result);
|
||||
|
||||
}
|
||||
|
||||
@@ -60,7 +60,6 @@ import org.springframework.messaging.tcp.ReconnectStrategy;
|
||||
import org.springframework.messaging.tcp.TcpConnectionHandler;
|
||||
import org.springframework.messaging.tcp.TcpOperations;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
@@ -83,7 +82,6 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
||||
private static final Method eventLoopGroupMethod = initEventLoopGroupMethod();
|
||||
|
||||
|
||||
|
||||
private final EventLoopGroup eventLoopGroup;
|
||||
|
||||
private final TcpClientFactory<Message<P>, Message<P>> tcpClientSpecFactory;
|
||||
@@ -107,7 +105,6 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
||||
* @param codec the codec to use for encoding and decoding the TCP stream
|
||||
*/
|
||||
public Reactor2TcpClient(final String host, final int port, final Codec<Buffer, Message<P>, Message<P>> codec) {
|
||||
|
||||
// Reactor 2.0.5 requires NioEventLoopGroup vs 2.0.6+ requires EventLoopGroup
|
||||
final NioEventLoopGroup nioEventLoopGroup = initEventLoopGroup();
|
||||
this.eventLoopGroup = nioEventLoopGroup;
|
||||
@@ -182,8 +179,8 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
||||
return new PassThroughPromiseToListenableFutureAdapter<Void>(
|
||||
promise.onError(new Consumer<Throwable>() {
|
||||
@Override
|
||||
public void accept(Throwable throwable) {
|
||||
connectionHandler.afterConnectFailure(throwable);
|
||||
public void accept(Throwable ex) {
|
||||
connectionHandler.afterConnectFailure(ex);
|
||||
}
|
||||
})
|
||||
);
|
||||
@@ -262,7 +259,7 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No compatible Reactor version found.");
|
||||
throw new IllegalStateException("No compatible Reactor version found");
|
||||
}
|
||||
|
||||
|
||||
@@ -270,8 +267,8 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
|
||||
|
||||
@Override
|
||||
public ReactorConfiguration read() {
|
||||
return new ReactorConfiguration(Collections.<DispatcherConfiguration>emptyList(),
|
||||
"sync", new Properties());
|
||||
return new ReactorConfiguration(
|
||||
Collections.<DispatcherConfiguration>emptyList(), "sync", new Properties());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator;
|
||||
|
||||
|
||||
/**
|
||||
* Adapts {@link WebSocketHandler} to the Jetty 9 WebSocket API.
|
||||
*
|
||||
@@ -59,8 +58,8 @@ public class JettyWebSocketHandlerAdapter {
|
||||
|
||||
|
||||
public JettyWebSocketHandlerAdapter(WebSocketHandler webSocketHandler, JettyWebSocketSession wsSession) {
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler must not be null");
|
||||
Assert.notNull(wsSession, "wsSession must not be null");
|
||||
Assert.notNull(webSocketHandler, "WebSocketHandler must not be null");
|
||||
Assert.notNull(wsSession, "WebSocketSession must not be null");
|
||||
this.webSocketHandler = webSocketHandler;
|
||||
this.wsSession = wsSession;
|
||||
}
|
||||
@@ -72,8 +71,8 @@ public class JettyWebSocketHandlerAdapter {
|
||||
this.wsSession.initializeNativeSession(session);
|
||||
this.webSocketHandler.afterConnectionEstablished(this.wsSession);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
|
||||
catch (Throwable ex) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,8 +82,8 @@ public class JettyWebSocketHandlerAdapter {
|
||||
try {
|
||||
this.webSocketHandler.handleMessage(this.wsSession, message);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
|
||||
catch (Throwable ex) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,8 +93,8 @@ public class JettyWebSocketHandlerAdapter {
|
||||
try {
|
||||
this.webSocketHandler.handleMessage(this.wsSession, message);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
|
||||
catch (Throwable ex) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,8 +106,8 @@ public class JettyWebSocketHandlerAdapter {
|
||||
try {
|
||||
this.webSocketHandler.handleMessage(this.wsSession, message);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
|
||||
catch (Throwable ex) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,8 +118,10 @@ public class JettyWebSocketHandlerAdapter {
|
||||
try {
|
||||
this.webSocketHandler.afterConnectionClosed(this.wsSession, closeStatus);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
logger.error("Unhandled error for " + this.wsSession, t);
|
||||
catch (Throwable ex) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Unhandled error for " + this.wsSession, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,8 +130,8 @@ public class JettyWebSocketHandlerAdapter {
|
||||
try {
|
||||
this.webSocketHandler.handleTransportError(this.wsSession, cause);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
|
||||
catch (Throwable ex) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-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.
|
||||
@@ -49,8 +49,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
|
||||
|
||||
|
||||
public StandardWebSocketHandlerAdapter(WebSocketHandler handler, StandardWebSocketSession wsSession) {
|
||||
Assert.notNull(handler, "handler must not be null");
|
||||
Assert.notNull(wsSession, "wsSession must not be null");
|
||||
Assert.notNull(handler, "WebSocketHandler must not be null");
|
||||
Assert.notNull(wsSession, "WebSocketSession must not be null");
|
||||
this.handler = handler;
|
||||
this.wsSession = wsSession;
|
||||
}
|
||||
@@ -58,7 +58,6 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
|
||||
|
||||
@Override
|
||||
public void onOpen(final javax.websocket.Session session, EndpointConfig config) {
|
||||
|
||||
this.wsSession.initializeNativeSession(session);
|
||||
|
||||
if (this.handler.supportsPartialMessages()) {
|
||||
@@ -100,9 +99,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
|
||||
try {
|
||||
this.handler.afterConnectionEstablished(this.wsSession);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
|
||||
return;
|
||||
catch (Throwable ex) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,8 +109,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
|
||||
try {
|
||||
this.handler.handleMessage(this.wsSession, textMessage);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
|
||||
catch (Throwable ex) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,8 +119,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
|
||||
try {
|
||||
this.handler.handleMessage(this.wsSession, binaryMessage);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
|
||||
catch (Throwable ex) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,8 +129,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
|
||||
try {
|
||||
this.handler.handleMessage(this.wsSession, pongMessage);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
|
||||
catch (Throwable ex) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,8 +140,10 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
|
||||
try {
|
||||
this.handler.afterConnectionClosed(this.wsSession, closeStatus);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
logger.error("Unhandled error for " + this.wsSession, t);
|
||||
catch (Throwable ex) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Unhandled error for " + this.wsSession, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,8 +152,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
|
||||
try {
|
||||
this.handler.handleTransportError(this.wsSession, exception);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, t, logger);
|
||||
catch (Throwable ex) {
|
||||
ExceptionWebSocketHandlerDecorator.tryCloseWithError(this.wsSession, ex, logger);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-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.
|
||||
@@ -25,16 +25,16 @@ import org.springframework.web.socket.WebSocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
/**
|
||||
* An exception handling {@link WebSocketHandlerDecorator}. Traps all {@link Throwable}
|
||||
* instances that escape from the decorated handler and closes the session with
|
||||
* {@link CloseStatus#SERVER_ERROR}.
|
||||
* An exception handling {@link WebSocketHandlerDecorator}.
|
||||
* Traps all {@link Throwable} instances that escape from the decorated
|
||||
* handler and closes the session with {@link CloseStatus#SERVER_ERROR}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class ExceptionWebSocketHandlerDecorator extends WebSocketHandlerDecorator {
|
||||
|
||||
private final Log logger = LogFactory.getLog(ExceptionWebSocketHandlerDecorator.class);
|
||||
private static final Log logger = LogFactory.getLog(ExceptionWebSocketHandlerDecorator.class);
|
||||
|
||||
|
||||
public ExceptionWebSocketHandlerDecorator(WebSocketHandler delegate) {
|
||||
@@ -52,20 +52,6 @@ public class ExceptionWebSocketHandlerDecorator extends WebSocketHandlerDecorato
|
||||
}
|
||||
}
|
||||
|
||||
public static void tryCloseWithError(WebSocketSession session, Throwable exception, Log logger) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Closing due to exception for " + session, exception);
|
||||
}
|
||||
if (session.isOpen()) {
|
||||
try {
|
||||
session.close(CloseStatus.SERVER_ERROR);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
|
||||
try {
|
||||
@@ -91,8 +77,25 @@ public class ExceptionWebSocketHandlerDecorator extends WebSocketHandlerDecorato
|
||||
try {
|
||||
getDelegate().afterConnectionClosed(session, closeStatus);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
logger.error("Unhandled error for " + this, t);
|
||||
catch (Throwable ex) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Unhandled error for " + this, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void tryCloseWithError(WebSocketSession session, Throwable exception, Log logger) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Closing due to exception for " + session, exception);
|
||||
}
|
||||
if (session.isOpen()) {
|
||||
try {
|
||||
session.close(CloseStatus.SERVER_ERROR);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-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.
|
||||
@@ -22,10 +22,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
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.util.Assert;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.WebSocketMessage;
|
||||
@@ -69,11 +67,13 @@ public class PerConnectionWebSocketHandler implements WebSocketHandler, BeanFact
|
||||
this.supportsPartialMessages = supportsPartialMessages;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.provider.setBeanFactory(beanFactory);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
WebSocketHandler handler = this.provider.getHandler();
|
||||
@@ -86,12 +86,6 @@ public class PerConnectionWebSocketHandler implements WebSocketHandler, BeanFact
|
||||
getHandler(session).handleMessage(session, message);
|
||||
}
|
||||
|
||||
private WebSocketHandler getHandler(WebSocketSession session) {
|
||||
WebSocketHandler handler = this.handlers.get(session);
|
||||
Assert.isTrue(handler != null, "WebSocketHandler not found for " + session);
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
|
||||
getHandler(session).handleTransportError(session, exception);
|
||||
@@ -103,19 +97,7 @@ public class PerConnectionWebSocketHandler implements WebSocketHandler, BeanFact
|
||||
getHandler(session).afterConnectionClosed(session, closeStatus);
|
||||
}
|
||||
finally {
|
||||
destroy(session);
|
||||
}
|
||||
}
|
||||
|
||||
private void destroy(WebSocketSession session) {
|
||||
WebSocketHandler handler = this.handlers.remove(session);
|
||||
try {
|
||||
if (handler != null) {
|
||||
this.provider.destroy(handler);
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
logger.warn("Error while destroying " + handler, t);
|
||||
destroyHandler(session);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +106,30 @@ public class PerConnectionWebSocketHandler implements WebSocketHandler, BeanFact
|
||||
return this.supportsPartialMessages;
|
||||
}
|
||||
|
||||
|
||||
private WebSocketHandler getHandler(WebSocketSession session) {
|
||||
WebSocketHandler handler = this.handlers.get(session);
|
||||
if (handler == null) {
|
||||
throw new IllegalStateException("WebSocketHandler not found for " + session);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
private void destroyHandler(WebSocketSession session) {
|
||||
WebSocketHandler handler = this.handlers.remove(session);
|
||||
try {
|
||||
if (handler != null) {
|
||||
this.provider.destroy(handler);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Error while destroying " + handler, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PerConnectionWebSocketHandlerProxy[handlerType=" + this.provider.getHandlerType() + "]";
|
||||
|
||||
@@ -18,8 +18,8 @@ package org.springframework.web.socket.messaging;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -86,7 +86,7 @@ public class SubProtocolWebSocketHandler
|
||||
private final Map<String, SubProtocolHandler> protocolHandlerLookup =
|
||||
new TreeMap<String, SubProtocolHandler>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
private final Set<SubProtocolHandler> protocolHandlers = new HashSet<SubProtocolHandler>();
|
||||
private final Set<SubProtocolHandler> protocolHandlers = new LinkedHashSet<SubProtocolHandler>();
|
||||
|
||||
private SubProtocolHandler defaultProtocolHandler;
|
||||
|
||||
@@ -171,7 +171,7 @@ public class SubProtocolWebSocketHandler
|
||||
public void setDefaultProtocolHandler(SubProtocolHandler defaultProtocolHandler) {
|
||||
this.defaultProtocolHandler = defaultProtocolHandler;
|
||||
if (this.protocolHandlerLookup.isEmpty()) {
|
||||
setProtocolHandlers(Arrays.asList(defaultProtocolHandler));
|
||||
setProtocolHandlers(Collections.singletonList(defaultProtocolHandler));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,8 +262,10 @@ public class SubProtocolWebSocketHandler
|
||||
try {
|
||||
holder.getSession().close(CloseStatus.GOING_AWAY);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
logger.error("Failed to close '" + holder.getSession() + "': " + t.getMessage());
|
||||
catch (Throwable ex) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Failed to close '" + holder.getSession() + "': " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,36 +292,6 @@ public class SubProtocolWebSocketHandler
|
||||
findProtocolHandler(session).afterSessionStarted(session, this.clientInboundChannel);
|
||||
}
|
||||
|
||||
protected final SubProtocolHandler findProtocolHandler(WebSocketSession session) {
|
||||
String protocol = null;
|
||||
try {
|
||||
protocol = session.getAcceptedProtocol();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Shouldn't happen
|
||||
logger.error("Failed to obtain session.getAcceptedProtocol(). Will use the " +
|
||||
"default protocol handler (if configured).", ex);
|
||||
}
|
||||
SubProtocolHandler handler;
|
||||
if (!StringUtils.isEmpty(protocol)) {
|
||||
handler = this.protocolHandlerLookup.get(protocol);
|
||||
Assert.state(handler != null, "No handler for '" + protocol + "' among " + this.protocolHandlerLookup);
|
||||
}
|
||||
else {
|
||||
if (this.defaultProtocolHandler != null) {
|
||||
handler = this.defaultProtocolHandler;
|
||||
}
|
||||
else if (this.protocolHandlers.size() == 1) {
|
||||
handler = this.protocolHandlers.iterator().next();
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Multiple protocol handlers configured and " +
|
||||
"no protocol was negotiated. Consider configuring a default SubProtocolHandler.");
|
||||
}
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an inbound message from a WebSocket client.
|
||||
*/
|
||||
@@ -378,6 +350,56 @@ public class SubProtocolWebSocketHandler
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
|
||||
this.stats.incrementTransportError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
|
||||
clearSession(session, closeStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPartialMessages() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected final SubProtocolHandler findProtocolHandler(WebSocketSession session) {
|
||||
String protocol = null;
|
||||
try {
|
||||
protocol = session.getAcceptedProtocol();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Shouldn't happen
|
||||
logger.error("Failed to obtain session.getAcceptedProtocol(). " +
|
||||
"Will use the default protocol handler (if configured).", ex);
|
||||
}
|
||||
|
||||
SubProtocolHandler handler;
|
||||
if (!StringUtils.isEmpty(protocol)) {
|
||||
handler = this.protocolHandlerLookup.get(protocol);
|
||||
if (handler == null) {
|
||||
throw new IllegalStateException(
|
||||
"No handler for '" + protocol + "' among " + this.protocolHandlerLookup);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.defaultProtocolHandler != null) {
|
||||
handler = this.defaultProtocolHandler;
|
||||
}
|
||||
else if (this.protocolHandlers.size() == 1) {
|
||||
handler = this.protocolHandlers.iterator().next();
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Multiple protocol handlers configured and " +
|
||||
"no protocol was negotiated. Consider configuring a default SubProtocolHandler.");
|
||||
}
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
private String resolveSessionId(Message<?> message) {
|
||||
for (SubProtocolHandler handler : this.protocolHandlerLookup.values()) {
|
||||
String sessionId = handler.resolveSessionId(message);
|
||||
@@ -408,6 +430,7 @@ public class SubProtocolWebSocketHandler
|
||||
if (!isRunning() || (currentTime - this.lastSessionCheckTime < TIME_TO_FIRST_MESSAGE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.sessionCheckLock.tryLock()) {
|
||||
try {
|
||||
for (WebSocketSessionHolder holder : this.sessions.values()) {
|
||||
@@ -427,8 +450,10 @@ public class SubProtocolWebSocketHandler
|
||||
this.stats.incrementNoMessagesReceivedCount();
|
||||
session.close(CloseStatus.SESSION_NOT_RELIABLE);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
logger.error("Failure while closing " + session, t);
|
||||
catch (Throwable ex) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Failure while closing " + session, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -439,16 +464,6 @@ public class SubProtocolWebSocketHandler
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
|
||||
this.stats.incrementTransportError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
|
||||
clearSession(session, closeStatus);
|
||||
}
|
||||
|
||||
private void clearSession(WebSocketSession session, CloseStatus closeStatus) throws Exception {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Clearing session " + session.getId());
|
||||
@@ -459,16 +474,13 @@ public class SubProtocolWebSocketHandler
|
||||
findProtocolHandler(session).afterSessionEnded(session, closeStatus, this.clientInboundChannel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPartialMessages() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SubProtocolWebSocketHandler" + getProtocolHandlers();
|
||||
return "SubProtocolWebSocketHandler" + this.protocolHandlers;
|
||||
}
|
||||
|
||||
|
||||
private static class WebSocketSessionHolder {
|
||||
|
||||
private final WebSocketSession session;
|
||||
@@ -477,7 +489,6 @@ public class SubProtocolWebSocketHandler
|
||||
|
||||
private volatile boolean handledMessages;
|
||||
|
||||
|
||||
private WebSocketSessionHolder(WebSocketSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
@@ -500,11 +511,12 @@ public class SubProtocolWebSocketHandler
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WebSocketSessionHolder[=session=" + this.session + ", createTime=" +
|
||||
return "WebSocketSessionHolder[session=" + this.session + ", createTime=" +
|
||||
this.createTime + ", hasHandledMessages=" + this.handledMessages + "]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class Stats {
|
||||
|
||||
private final AtomicInteger total = new AtomicInteger();
|
||||
@@ -521,7 +533,6 @@ public class SubProtocolWebSocketHandler
|
||||
|
||||
private final AtomicInteger transportError = new AtomicInteger();
|
||||
|
||||
|
||||
public void incrementSessionCount(WebSocketSession session) {
|
||||
getCountFor(session).incrementAndGet();
|
||||
this.total.incrementAndGet();
|
||||
|
||||
Reference in New Issue
Block a user