Search code examples
spring-integrationspring-websocket

How do I use the StompSubProtocolHandler with the int-websocket:client-container


I have a basic setup for a Websocket Stomp Client. The problem is that the StompSubProtocolHandler, WebsocketInboundChannelAdapter and the WebsocketOutboundMessageHandler treat messages as if the application is a server.

The messages get special treatment depending on whether they are inbound or outbound.

For example, I send a message through the outbound-channel-adapter with simpMessageType="CONNECT" and the StompSubProtocolHandler's handleMessageToClient [thankfully] does not do what it is supposed to do with a CONNECT message because it does not expect such a message to be sent.

Then a CONNECTED [CONNECT_ACT] message comes back and is handled by the StompSubProtcolHandler's handleMessageFromClient function. This function doesn't know what to do with this CONNECTED frame and instead of publishEvent it attempts to send the message to the outputChannel. This would be ok except that the WebsocketInboundChannelAdapter is aware of simpMessageTypes and ignores the message because it is not a "MESSAGE" type.

I feel like there must be some kind of client side websocket channel adapters that I don't know about. I also feel like there must be some kind of StompSubProtocolHandler that is designed with the client in mind as well. There are not a lot of examples applications using the int-websocket:client-container and I am at a loss of what to do.

Can anybody please help me understand what I need to do to handle STOMP messages as a websocket client?

<int-websocket:client-container id="websocketClientContainer"
                                client="websocketStompClient" 
                                uri="ws://localhost:8080/stomp" />

<bean id="stompSubProtocolHandler"
      class="org.springframework.web.socket.messaging.StompSubProtocolHandler"/>

<int-websocket:inbound-channel-adapter 
             channel="receiveMessage"
             container="websocketClientContainer"
             default-protocol-handler="stompSubProtocolHandler"/>

<int:channel id="receiveMessage" />

<int:service-activator ref="websocketStompClient" 
         method="receiveNotification" 
         input-channel="receiveMessage" 
         output-channel="nullChannel" />

<int-event:inbound-channel-adapter 
      event-types="org.springframework.web.socket.messaging.AbstractSubProtocolEvent"
      payload-expression="message"
      channel="routeStompEvents"/>

<int:channel id="routeStompEvents" />

<int:router ref="StompInboundMessageTypeRouter"
                method="routeStompMessage"
                input-channel="routeStompEvents" 
                default-output-channel="nullChannel" 
                resolution-required="false" />

Solution

  • Well, what I want to confirm that CONNECT as a message to the <int-websocet:outbound-channel-adapter> from the client side works well.

    We have just missed to handle StompCommand.CONNECTED in the WebSocketInboundChannelAdapter from client side, which looks like should be emitted as a SessionConnectedEvent as a confirmation from the server.

    Another missed STOMP Frame is StompCommand.RECEIPT, which should be emitted like some new StompReceiptEvent.

    Feel free to raise a JIRA issue on the matter, and we'll take a look to the stomp-chat afterwards to add the Java Client as well.

    More smooth integration with STOPM as Client we can address with some new int-stopm components.

    UPDATE

    The JIRA on the matter: https://jira.spring.io/browse/INT-3686 To fully support STOMP protocol with adapters we have another ticket: https://jira.spring.io/browse/INT-3685