-
Notifications
You must be signed in to change notification settings - Fork 38.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix IllegalArgumentException that prevents STOMP DISCONNECT from reaching the client #30120
Fix IllegalArgumentException that prevents STOMP DISCONNECT from reaching the client #30120
Conversation
In some application setups, the WebSocket server does not transmit the disconnect message to the client, so that the client has no idea that the established connection has been terminated. This issue arises when the application uses SimpleBrokerMessageHandler and the error handler is set to the instance of StompSubProtocolErrorHandler or an extended class that does not override the handleErrorMessageToClient method. The commit fixes disconnect message population so that `java.lang.IllegalArgumentException: No StompHeaderAccessor` exception is not thrown in the handleErrorMessageToClient method in StompSubProtocolErrorHandler class.
e3cdd8d
to
cb785e1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey @alexjansons, thanks for the PR! Would you be able to produce a unit test or compact integration test that reproduces the issue and validates the fix?
@@ -465,7 +465,9 @@ else if (StompCommand.CONNECTED.equals(command)) { | |||
} | |||
|
|||
if (StompCommand.ERROR.equals(command) && getErrorHandler() != null) { | |||
Message<byte[]> errorMessage = getErrorHandler().handleErrorMessageToClient((Message<byte[]>) message); | |||
Message<byte[]> enrichedMessage = | |||
MessageBuilder.createMessage((byte[]) message.getPayload(), accessor.getMessageHeaders()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: rather than casting, you can use payload
from the instanceOf at the top
In some application setups, the WebSocket server does not transmit the disconnect message to the client, so that the client has no idea that the established connection has been terminated. This issue arises when the application uses SimpleBrokerMessageHandler and the error handler is set to the instance of StompSubProtocolErrorHandler or an extended class that does not override the handleErrorMessageToClient method. The commit fixes disconnect message population so that `java.lang.IllegalArgumentException: No StompHeaderAccessor` exception is not thrown in the handleErrorMessageToClient method in StompSubProtocolErrorHandler class. See gh-30120
In some application setups, the WebSocket server does not transmit the disconnect message to the client, so that the client has no idea that the established connection has been terminated.
This issue arises when the application uses SimpleBrokerMessageHandler and the error handler is set to the instance of
StompSubProtocolErrorHandler or an extended class that does not override the handleErrorMessageToClient method.
The commit fixes disconnect message population so that
java.lang.IllegalArgumentException: No StompHeaderAccessor
exception is not thrown in the handleErrorMessageToClient method in StompSubProtocolErrorHandler class.A reproducible example for the case is available here:
The issue arises when the client fails to send heartbeats for specific period, causing the server to terminate the session by invoking the
handleDisconnect
method in theSimpleBrokerMessageHandler.HeartbeatTask
class. This issue was discovered in spring-websocket-5.3.13 but still persists in the latest code base.If the error handler is not set, then there is no problem as the message is delivered to the client in this scenario. A reproducible example that illustrates this is the
DisconnectWithoutErrorHandler.test
found at https://github.com/alexjansons/spring-sandbox/blob/main/web-socket/disconnect-error/src/test/java/com/example/websocket/disconnecterror/ApplicationTests.java#L97.However if the error handler is set to
StompSubProtocolErrorHandler
class instance or the instance of extended class given that the latter does not implement it's ownhandleErrorMessageToClient
method, the disconnect message transmission process faces theIllegalArgumentException
exception in the aforementioned method. The exception is caught and then silently ignored inSubProtocolWebSocketHandler.handleMessage
method, which results in no message being sent to the client. This case is covered inDisconnectWithErrorHandler.test
at https://github.com/alexjansons/spring-sandbox/blob/main/web-socket/disconnect-error/src/test/java/com/example/websocket/disconnecterror/ApplicationTests.java#L83.A workaround for this issue is to extend the
StompSubProtocolErrorHandler
class for the error handler and re-implement the methodhandleErrorMessageToClient
so that it does not generate an exception. An example of this workaround can be found at https://github.com/alexjansons/spring-sandbox/blob/main/web-socket/disconnect-error/src/main/java/com/example/websocket/disconnecterror/Application.java#L24.