javaactivemq-classicstompconsumer

ActiveMQ Java STOMP client receives SocketTimeoutException


There is an ActiveMQ server working on CentOS machine. I can connect and consume messages with TCP and HTTP using the OpenWire JMS client. However, When I tried with the ActiveMQ test STOMP client it throws this exception on connection.receieve;

java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.net.SocketInputStream.read(SocketInputStream.java:224)
    at java.io.DataInputStream.readByte(DataInputStream.java:265)
    at org.apache.activemq.transport.stomp.StompWireFormat.readHeaderLine(StompWireFormat.java:174)
    at org.apache.activemq.transport.stomp.StompWireFormat.readLine(StompWireFormat.java:167)
    at org.apache.activemq.transport.stomp.StompWireFormat.parseAction(StompWireFormat.java:200)
    at org.apache.activemq.transport.stomp.StompWireFormat.unmarshal(StompWireFormat.java:112)
    at org.apache.activemq.transport.stomp.StompConnection.receive(StompConnection.java:77)
    at tr.com.estherial.stomplistener.StompListener.main(StompListener.java:25)

Listener Class

import org.apache.activemq.transport.stomp.Stomp;
import org.apache.activemq.transport.stomp.StompConnection;
import org.apache.activemq.transport.stomp.StompFrame;
 
public class StompListener {

    public static void main(String[] args) { 

        StompConnection connection = new StompConnection();
        try {
            connection.open("host", 61613);
            connection.connect("admin", "admin", "test");
            connection.subscribe("TEST_TOPIC", Stomp.Headers.Subscribe.AckModeValues.CLIENT);
            connection.begin("test"); 

            while (true) {
                try {
                    StompFrame message = connection.receive(10000); 
                    System.out.println(String.format("%s - Receiver: received '%s'", new Date(), message.getBody()));
                } catch (SocketTimeoutException e) {
                    // ignore
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

This is the connector in activemq.xml:

<transportConnectors>
    <transportConnector name="stomp" uri="stomp://localhost:61613"/>
</transportConnectors>

Did you get similar exception before?


Solution

  • The java.net.SocketTimeoutException is expected when the STOMP subscriber receives no message within the specified timeout. Once the client creates his subscription you need to send a message to the topic. At that point the client should receive the message and print it via your System.out.println.

    Also, in ActiveMQ 5.x when subscribing to a destination from a STOMP client you need to prefix the destination name with either /queue/ or /topic/. You aren't doing this in your application. Try using this:

    connection.subscribe("/topic/TEST_TOPIC", Stomp.Headers.Subscribe.AckModeValues.CLIENT);
    

    Lastly, it's worth noting that you're using the test STOMP client from the ActiveMQ code-base. This client is used by ActiveMQ's internal test-suite to verify the broker implementation is working as expected. It's not meant for general use. Furthermore, if you're using Java you would be better off using a better performing and more full-featured client like the OpenWire JMS client or even the Qpid JMS client.