Improve logging in STOMP broker relay

Ignore DISCONNECT messages if already disconnected. This can occur if
the client explicitly sends a DISCONNECT frame and then closes the
socket quickly. The closing of the WebSocket sessions also sends a
DISCONNECT upstream to ensure the broker is aware.
This commit is contained in:
Rossen Stoyanchev 2014-03-17 17:11:15 -04:00
parent 918e21fd8f
commit 57af56aeeb
1 changed files with 27 additions and 15 deletions

View File

@ -18,6 +18,7 @@ package org.springframework.messaging.simp.stomp;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.springframework.messaging.Message; import org.springframework.messaging.Message;
@ -36,6 +37,7 @@ import org.springframework.messaging.tcp.reactor.ReactorTcpClient;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback; import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.util.concurrent.ListenableFutureTask;
/** /**
* A {@link org.springframework.messaging.MessageHandler} that handles messages by forwarding them to a STOMP broker. * A {@link org.springframework.messaging.MessageHandler} that handles messages by forwarding them to a STOMP broker.
@ -68,6 +70,8 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
private static final byte[] EMPTY_PAYLOAD = new byte[0]; private static final byte[] EMPTY_PAYLOAD = new byte[0];
private static final ListenableFutureTask<Void> EMPTY_TASK = new ListenableFutureTask<Void>(new VoidCallable());
// STOMP recommends error of margin for receiving heartbeats // STOMP recommends error of margin for receiving heartbeats
private static final long HEARTBEAT_MULTIPLIER = 3; private static final long HEARTBEAT_MULTIPLIER = 3;
@ -627,6 +631,9 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
if (!this.isStompConnected) { if (!this.isStompConnected) {
if (this.isRemoteClientSession) { if (this.isRemoteClientSession) {
if (StompCommand.DISCONNECT.equals(StompHeaderAccessor.wrap(message).getCommand())) {
return EMPTY_TASK;
}
// Should never happen // Should never happen
throw new IllegalStateException("Unexpected client message " + message + throw new IllegalStateException("Unexpected client message " + message +
(this.tcpConnection != null ? (this.tcpConnection != null ?
@ -681,23 +688,20 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
*/ */
public void clearConnection() { public void clearConnection() {
if (this.isRemoteClientSession) {
if (logger.isDebugEnabled()) {
logger.debug("Removing session '" + sessionId + "' (total remaining=" +
(StompBrokerRelayMessageHandler.this.connectionHandlers.size() - 1) + ")");
}
StompBrokerRelayMessageHandler.this.connectionHandlers.remove(this.sessionId);
}
this.isStompConnected = false; this.isStompConnected = false;
try { TcpConnection<byte[]> conn = this.tcpConnection;
TcpConnection<byte[]> conn = this.tcpConnection; this.tcpConnection = null;
this.tcpConnection = null; if (conn != null) {
if (conn != null) { conn.close();
conn.close();
}
}
finally {
if (this.isRemoteClientSession) {
if (logger.isDebugEnabled()) {
logger.debug("Removing session '" + sessionId + "' (total remaining=" +
(StompBrokerRelayMessageHandler.this.connectionHandlers.size() - 1) + ")");
}
StompBrokerRelayMessageHandler.this.connectionHandlers.remove(this.sessionId);
}
} }
} }
@ -754,4 +758,12 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
} }
} }
private static class VoidCallable implements Callable<Void> {
@Override
public Void call() throws Exception {
return null;
}
}
} }