На машине CentOS работает сервер ActiveMQ. Я могу подключаться и получать сообщения по TCP и HTTP с помощью клиента OpenWire JMS. Однако, когда я пытался использовать клиент STOMP для тестирования ActiveMQ, он генерировал это исключение на 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)

Класс слушателя

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();
        }
    }
}

Это соединитель в activemq.xml:

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

Вы получали подобное исключение раньше?

0
estherial 12 Фев 2021 в 18:42

1 ответ

Лучший ответ

java.net.SocketTimeoutException ожидается, когда подписчик STOMP не получит сообщения в течение указанного тайм-аута. Как только клиент создаст свою подписку, вам необходимо отправить сообщение в тему. В этот момент клиент должен получить сообщение и распечатать его через System.out.println.

Кроме того, в ActiveMQ 5.x при подписке на пункт назначения от клиента STOMP вам необходимо добавить к имени пункта назначения префикс /queue/ или /topic/. Вы не делаете этого в своем приложении. Попробуйте использовать это:

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

Наконец, стоит отметить, что вы используете клиент STOMP test из базы кода ActiveMQ. Этот клиент используется внутренним набором тестов ActiveMQ для проверки того, что реализация брокера работает должным образом. Он не предназначен для общего пользования. Кроме того, если вы используете Java, вам лучше использовать более производительный и более полнофункциональный клиент, такой как клиент OpenWire JMS или даже клиент Qpid JMS.

0
Justin Bertram 14 Фев 2021 в 01:48