Search code examples
node.jsstompactivemq-artemis

Connection timeout using nodejs stompit when connecting to activemq artemis


I am making stompit connection to my ActiveMQ Artemis broker and I see no error when calling connect. After some time (in few mins) I see Connection timeout error.

Also, I am not seeing the queue being created (only address) getting created and the message is not seen at the Artemis console.

enter image description here

ActiveMQ Artemis console:

enter image description here

Code:

const stompConnectOptions= {
    'host': 'localhost',
    'port': 61613,
    'connectHeaders': {
        'host': '/', 'login': 'admin', 'passcode': 'xxxx', 'heart-beat': '1000,1000'
    }
};

const stompit=require ('stompit') const subscribeHeaders= {
    'destination': 'emailEvent', 'ack': 'client-individual'
};

const sendHeaders= {
    'destination': '/queue/TestEvent', 'content-type': 'text/plain'
};

stompit.connect(stompConnectOptions, (err, client)=> {
    if (err) {
        console.log("error with stomp connection.");
        return;
    }
    console.log("stomp connected") stompClient=client;
    const frame=client.send(sendHeaders);
    frame.write('hello');
    frame.end();
    console.log('hello message sent')
});

ActiveMQ server logs:

enter image description here

2020-01-29 23:33:46,333 WARN  [org.apache.activemq.artemis.core.protocol.stomp] AMQ332069: Sent ERROR frame to STOMP client /127.0.0.1:52170: null
2020-01-29 23:33:46,334 WARN  [org.apache.activemq.artemis.core.server] AMQ222067: Connection failure has been detected: null [code=REMOTE_DISCONNECT]
2020-01-29 23:33:46,335 WARN  [org.apache.activemq.artemis.core.server] AMQ222061: Client connection failed, clearing up resources for session 21617631-4319-11ea-a1bd-24a2e1f3b27a
2020-01-29 23:33:46,337 WARN  [org.apache.activemq.artemis.core.server] AMQ222107: Cleared up resources for session 21617631-4319-11ea-a1bd-24a2e1f3b27a

I am new to stompit.


Solution

  • The ActiveMQ Artemis STOMP documentation should be helpful here.

    The first thing I recommend is enabling debug logging. The documentation states:

    Incoming and outgoing STOMP frames can be logged by enabling DEBUG for org.apache.activemq.artemis.core.protocol.stomp.StompConnection. This can be extremely useful for debugging or simply monitoring client activity. Along with the STOMP frame itself the remote IP address of the client is logged as well as the internal connection ID so that frames from the same client can be correlated.

    You can enable this logging by modifying etc/logging.properties.

    First, add this to the comma-separated loggers list at the beginning of the file:

    org.apache.activemq.artemis.core.protocol.stomp.StompConnection
    

    Second, add a new line with this under the ActiveMQ Artemis logger levels comment:

    logger.org.apache.activemq.artemis.core.protocol.stomp.StompConnection.level=DEBUG
    

    Once you have the logging enabled it should help you see why the connection is being closed. My guess is that the client is not sending the proper heart-beating frames. In that case you can try connecting with no heartbeat, e.g.:

    const stompConnectOptions= {
        'host': 'localhost',
        'port': 61613,
        'connectHeaders': {
            'host': '/', 'login': 'admin', 'passcode': 'xxxx', 'heart-beat': '0,0'
        }
    };
    

    The documentation should also help explain why only an address is being created and not a queue as well. In the "Sending" section the documentation states:

    When a STOMP client sends a message (using a SEND frame), the protocol manager looks at the message to determine where to route it and potentially how to create the address and/or queue to which it is being sent. The protocol manager uses either of the following bits of information from the frame to determine the routing type:

    1. The value of the destination-type header. Valid values are ANYCAST and MULTICAST (case sensitive).

    2. The "prefix" on the destination header. See additional info on prefixes.

    If no indication of routing type is supplied then the default defined in the corresponding default-address-routing-type & default-queue-routing-type address-settings will be used.

    The destination header maps to an address of the same name. If the destination header used a prefix then the prefix is stripped.

    When you send your message the broker is using the MULTICAST routing type which means it will only auto-create the address and not a queue. This is the default behavior.

    As noted in the documentation you have 3 main options to resolve this...

    One, you can send the destination-type header, e.g.:

    const sendHeaders= {
        'destination': '/queue/TestEvent', 'content-type': 'text/plain', 'destination-type': 'ANYCAST'
    };
    

    Two, you can configure a prefix on the STOMP acceptor like is done in the "stomp-jms" example shipped with the broker, e.g.:

    <acceptor name="stomp">tcp://0.0.0.0:61613?anycastPrefix=/queue/</acceptor>
    

    Three, you can change the default routing types via address-settings, e.g.:

    <address-setting match="#">
       ...
       <default-address-routing-type>ANYCAST</default-address-routing-type>
       <default-queue-routing-type>ANYCAST</default-queue-routing-type>
       ...
    </address-setting>
    

    Of course, using a match of # will change the default for every address & queue so you may want to tune that for your specific needs.