Skip to content

Commit 01aa64c

Browse files
committed
Simple broker sends notice after disconnect
Before this change the simple broker simply removed subscriptions upon receiving a DISCONNECT message assuming it was a result of a client STOMP WebSocket session ending. However, if the server-side application sends a DISCONNECT to the broker in order to terminate a session, the STOMP WebSocket session could remain unware without any further action. This change ensures the simple broker sends a DISCONNECT_ACK message downstream whenever it receives a DISCONNECT. Issue: SPR-12288
1 parent 6463878 commit 01aa64c

File tree

4 files changed

+21
-5
lines changed

4 files changed

+21
-5
lines changed

spring-messaging/src/main/java/org/springframework/messaging/simp/SimpMessageType.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public enum SimpMessageType {
3939

4040
DISCONNECT,
4141

42+
DISCONNECT_ACK,
43+
4244
OTHER;
4345

4446
}

spring-messaging/src/main/java/org/springframework/messaging/simp/broker/SimpleBrokerMessageHandler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ else if (SimpMessageType.DISCONNECT.equals(messageType)) {
169169
logger.debug("Processing " + accessor.getShortLogMessage(EMPTY_PAYLOAD));
170170
}
171171
this.subscriptionRegistry.unregisterAllSubscriptions(sessionId);
172+
SimpMessageHeaderAccessor disconnectAck = SimpMessageHeaderAccessor.create(SimpMessageType.DISCONNECT_ACK);
173+
initHeaders(disconnectAck);
174+
disconnectAck.setSessionId(sessionId);
175+
Message<byte[]> messageOut = MessageBuilder.createMessage(EMPTY_PAYLOAD, disconnectAck.getMessageHeaders());
176+
getClientOutboundChannel().send(messageOut);
172177
}
173178
else if (SimpMessageType.SUBSCRIBE.equals(messageType)) {
174179
if (logger.isDebugEnabled()) {

spring-messaging/src/test/java/org/springframework/messaging/simp/broker/SimpleBrokerMessageHandlerTests.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
package org.springframework.messaging.simp.broker;
1818

19+
import static org.junit.Assert.assertEquals;
20+
import static org.mockito.Mockito.times;
21+
import static org.mockito.Mockito.verify;
22+
1923
import java.util.Collections;
2024

2125
import org.junit.Before;
@@ -24,17 +28,13 @@
2428
import org.mockito.Captor;
2529
import org.mockito.Mock;
2630
import org.mockito.MockitoAnnotations;
27-
2831
import org.springframework.messaging.Message;
2932
import org.springframework.messaging.MessageChannel;
3033
import org.springframework.messaging.SubscribableChannel;
3134
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
3235
import org.springframework.messaging.simp.SimpMessageType;
3336
import org.springframework.messaging.support.MessageBuilder;
3437

35-
import static org.junit.Assert.*;
36-
import static org.mockito.Mockito.*;
37-
3838
/**
3939
* Unit tests for SimpleBrokerMessageHandler.
4040
*
@@ -115,7 +115,12 @@ public void subcribeDisconnectPublish() {
115115
this.messageHandler.handleMessage(createMessage("/foo", "message1"));
116116
this.messageHandler.handleMessage(createMessage("/bar", "message2"));
117117

118-
verify(this.clientOutboundChannel, times(3)).send(this.messageCaptor.capture());
118+
verify(this.clientOutboundChannel, times(4)).send(this.messageCaptor.capture());
119+
120+
Message<?> captured = this.messageCaptor.getAllValues().get(0);
121+
assertEquals(SimpMessageType.DISCONNECT_ACK, SimpMessageHeaderAccessor.getMessageType(captured.getHeaders()));
122+
assertEquals(sess1, SimpMessageHeaderAccessor.getSessionId(captured.getHeaders()));
123+
119124
assertCapturedMessage(sess2, "sub1", "/foo");
120125
assertCapturedMessage(sess2, "sub2", "/foo");
121126
assertCapturedMessage(sess2, "sub3", "/bar");

spring-websocket/src/main/java/org/springframework/web/socket/messaging/StompSubProtocolHandler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ else if (accessor instanceof SimpMessageHeaderAccessor) {
393393
if (SimpMessageType.CONNECT_ACK.equals(stompAccessor.getMessageType())) {
394394
stompAccessor = convertConnectAcktoStompConnected(stompAccessor);
395395
}
396+
else if (SimpMessageType.DISCONNECT_ACK.equals(stompAccessor.getMessageType())) {
397+
stompAccessor = StompHeaderAccessor.create(StompCommand.ERROR);
398+
stompAccessor.setMessage("Session closed.");
399+
}
396400
else if (stompAccessor.getCommand() == null || StompCommand.SEND.equals(stompAccessor.getCommand())) {
397401
stompAccessor.updateStompCommandAsServerMessage();
398402
}

0 commit comments

Comments
 (0)