TooTallNate / Java-WebSocket

A barebones WebSocket client and server implementation written in 100% Java.

Home Page:http://tootallnate.github.io/Java-WebSocket

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unable to consume STOMP data

debashis1982 opened this issue · comments

Describe the bug
I am trying to connect and receive data from a remote websocket endpoint that used STOMP messages.
While I am able to connect to it and send subscribe messages, I am not able to receive any data.
The data sent my the websocket data is byte array and I do not see onMessage(String message) or onMessage(ByteBuffer bytes) getting triggered on the client side.

Is there a way to solve this? Or is there a way to get some verbose logs that could indicate where the problem is?

To Reproduce
Steps to reproduce the behavior:

  1. Connect to a STOMP based websocket endpoint that sends back data in the form of byte[]
  2. Try to receive that data

Environment(please complete the following information):

  • Version used: 1.5.5
  • Java version: 17
  • Operating System and version: MacOS 13.6
  • Endpoint Name and version:
  • Link to your project:

Additional context
I am able to consume data using Spring framework's stomp client but I need a non Spring solution. Thanks!

Please provide an example STOMP server

Here is a good example on how to create a stomp server and a client - https://www.toptal.com/java/stomp-spring-boot-websocket

Please provide a full example application

Hi, I can look into your issue over the weekend, but from what I see it is unlikely that the problem is directly related to this library.

You can verify that no messages are arriving using Wireshark or similar tools.

My best guess is that the server does not send data at all (maybe you are subscribing incorrectly), so there is not much we can do without access to the server side.

Hi,
Actually I own the server side application as well and I am able to verify that the subscription process succeeded and data is being written. One more thing - onClose() method does get triggered when remote closes the websocket session.
I am also able to consume data via a Spring based websocket client. I will try to create two simple projects - one server side and one client side and share here.

I have uploaded a Springboot project that hosts a websocket endpoint : https://github.com/debashis1982/spring-stomp-websocket
I use Intellij Idea to run Application.java. It brings up the application on port 8080 and then I use the following client side code using this library to connect to the websocket endpoint - ws://localhost:8080/my-websocket
The websocket code writes a String message (not even in byte[] format as I stated in my original post) to the subscribe endpoint but none of the onMessage methods get invoked.

package com.client.websocket;

import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.util.UUID;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

public class SampleWebSocketClient {
    public static void main(String[] args) throws URISyntaxException, InterruptedException {

        final boolean[] isConnected = {false};
        WebSocketClient webSocketClient = new WebSocketClient(new URI("ws://localhost:8080/my-websocket")) {
            @Override
            public void onOpen(ServerHandshake handshakedata) {
                System.out.println("Opened connection to websocket");
                isConnected[0] = true;
            }

            @Override
            public void onMessage(String message) {
                System.out.println("Received string message through websocket");
            }

            @Override
            public void onMessage(ByteBuffer bytes) {
                System.out.println("Received binary message through websocket");
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                System.out.println("Closed connection to websocket>>"+reason);
            }

            @Override
            public void onError(Exception ex) {
                System.out.println("Received error through websocket");
                ex.printStackTrace();
            }
        };
        webSocketClient.connectBlocking();
        System.out.println("Connected?: "+webSocketClient.isOpen());
        try {
            String subscribeMessage = String.format("""
                                                    SUBSCRIBE
                                                    destination:/my-websocket-broker/subscribe/%s
                                                    id:%s
                                                                                                      
                                                    \0
                                                    """, UUID.randomUUID(),UUID.randomUUID());
            webSocketClient.send(subscribeMessage);
            System.out.println("sent subscribe message \n"+subscribeMessage);
            System.out.println("connection still open?: "+webSocketClient.isOpen());
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

Logs from the websocket server side code:

subscribe complete
sending data to /my-websocket-broker/subscribe/88377627-077a-46f9-bd35-5b3e6c926109

Logs from the client side code:

Opened connection to websocket
Connected?: true
sent subscribe message 
SUBSCRIBE
destination:/my-websocket-broker/subscribe/88377627-077a-46f9-bd35-5b3e6c926109
id:ca7c3f83-91a8-46df-90ab-8bce467de2b9

�

connection still open?: true

Not sure what I am doing wrong

As I predicted, this is not an issue with the library. You are missing a CONNECT stomp message before subscribing therefore Spring never sends you anything.
I added this code before sending the subscribe message:

            webSocketClient.send("CONNECT\naccept-version:1.2,1.1,1.0\n\n\000");
            Thread.sleep(1000); // lazy way to make sure we got answer

And now it works as expected

See https://stomp.github.io/stomp-specification-1.2.html#CONNECT_or_STOMP_Frame for more information
To verify this I just copied the sample browser code from https://github.com/stomp-js/stompjs and checked the packet differences in Wireshark, if you are implementing STOMP yourself I recommend you get familiar with this tool, it will save you a lot of headaches.

Closing as there is nothing more to do.

Thanks a lot @PhilipRoman Can't believe I missed it and spent so many hours on it. Apologies for wasting your time on this.