ActiveMQ supports the Stomp protocol and the Stomp - JMS mapping. This makes it easy to write a client in pure Ruby, Perl, Python or PHP for working with ActiveMQ. Please see the Stomp site for more details Spec Compliance ActiveMQ v5.6 implements the Stomp v1.1 spec except for allowing spaces at the beginning or end of message header keys, they are preserved in the header values however. In future releases this will not be the case, clients should be updated and user code checked to ensure that spaces in the headers are there intentionally and not as a accident or a client "feature". Enabling the ActiveMQ Broker for StompTo enable STOMP protocol support in the broker add a transport connector definition whose URI scheme is Example: <transportConnectors> <transportConnector name="stomp" uri="stomp://localhost:61613"/> </transportConnectors> To see a full example, try this XML. If you save that XML as activemq xbean:foo.xml For more help see Run Broker. The Stomp Wire FormatStomp uses a text based wire format that can be configured with the following options. All options can be configured on a Brokers transport bind URI.
Example: <transportConnector name="stomp+ssl" uri="stomp+ssl://localhost:61612?wireFormat.maxFrameSize=1000000"/> Use the Correct Prefix! Wire format options must have the prefix SecurityFrom ActiveMQ 5.1: Stomp fully supports ActiveMQ's security mechanism. This means that the SSL For additional security, you can use Stomp over SSL as described in the following section. Enabling Stomp over NIOFrom ActiveMQ 5.3: for better scalability and performance the Stomp protocol can be configured to be run over the NIO transport. The NIO transport will use far fewer threads than the corresponding TCP connector. This can help when support for a large number of queues is required. To use NIO change the URI scheme of the transport connector to Example: <transportConnector name="stomp+nio" uri="stomp+nio://localhost:61612"/> Enabling Stomp over SSLTo configure ActiveMQ to use Stomp over an SSL connection change the URI scheme to Example: <transportConnector name="stomp+ssl" uri="stomp+ssl://localhost:61612"/> For more details on using SSL with ActiveMQ see the following article (How do I use SSL). An example of using Stomp over SSL on the client side can be found in the PHP Stomp client example. Heart-Beat Grace PeriodThe STOMP protocol (version 1.1 or greater) defines the concept of heart beats as a method by which a client and broker can determine the health of the underlying TCP connection between them. ActiveMQ supports STOMP heart beating provided the client is using version 1.1 (or greater) of the protocol. Before ActiveMQ 5.9.0: enforcement of the 'read' heart-beat timeout (that is, a heart-beat sent from the client to the broker) was strict. In other words, the broker was intolerant of late arriving read heart-beats from the client. This resulted in the broker concluding that the client was no longer present causing it to close its side of the client's connection when the client failed to honor it's configured heart-beat settings. From ActiveMQ 5.9.0: the timeout enforcement for read heart-beats is now configurable via a new transport option <transportConnectors> <transportConnector name="stomp" uri="stomp://localhost:61613?transport.hbGracePeriodMultiplier=1.5"/> </transportConnectors> This multiplier is used to calculate the effective read heart-beat timeout the broker will enforce for each client's connection. The multiplier is applied to the read-timeout interval the client specifies in its
For backward compatibility, if the grace period multiplier is not configured the default enforcement mode remains strict, e.g., STOMP clients that wish to be tolerant of late arriving heart-beats from the broker must implement their own solution for doing so.
Working with Destinations with StompNote that the prefix in stomp Be careful about starting destinations with / If in Stomp world you use Persistent Messaging in STOMP STOMP messages are non-persistent by default. To use persistent messaging add the following STOMP header to all Working with JMS Text/Bytes Messages and StompStomp is a very simple protocol - that's part of the beauty of it! As such, it does not have knowledge of JMS messages such as
This same logic can be followed when going from JMS to Stomp, as well. A Stomp client could be written to key off of the inclusion of the Message TransformationsThe Here's a quick example of how to use built-in transformer (taken from test cases) private String xmlObject = "<pojo>\n" + " <name>Dejan</name>\n" + " <city>Belgrade</city>\n" + "</pojo>"; public void testTransformationReceiveXMLObject() throws Exception { MessageProducer producer = session.createProducer(new ActiveMQQueue("USERS." + getQueueName())); ObjectMessage message = session.createObjectMessage(new SamplePojo("Dejan", "Belgrade")); producer.send(message); String frame = "CONNECT\n" + "login: system\n" + "passcode: manager\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); frame = stompConnection.receiveFrame(); assertTrue(frame.startsWith("CONNECTED")); frame = "SUBSCRIBE\n" + "destination:/queue/USERS." + getQueueName() + "\n" + "ack:auto" + "\n" + "transformation:jms-object-xml\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); frame = stompConnection.receiveFrame(); assertTrue(frame.trim().endsWith(xmlObject)); frame = "DISCONNECT\n" + "\n\n" + Stomp.NULL; stompConnection.sendFrame(frame); } Dependencies In order to create your own transformer, you have to do the following:
For example the built-in transformer contains the following value: class=org.apache.activemq.transport.stomp.XStreamFrameTranslator in the DebuggingIn case you want to debug Stomp communication between broker and clients you should configure the Stomp connector with the <transportConnectors> <transportConnector name="stomp" uri="stomp://localhost:61613?trace=true"/> </transportConnectors> This will instruct the broker to trace all packets it sends and receives. Furthermore, you have to enable tracing for the appropriate log. You can achieve that by adding the following to your log4j.logger.org.apache.activemq.transport.stomp=TRACE Finally, you will probably want to keep these messages in the separate file instead of polluting the standard broker's log. You can achieve that with the following log4j configuration: log4j.appender.stomp=org.apache.log4j.RollingFileAppender log4j.appender.stomp.file=${activemq.base}/data/stomp.log log4j.appender.stomp.maxFileSize=1024KB log4j.appender.stomp.maxBackupIndex=5 log4j.appender.stomp.append=true log4j.appender.stomp.layout=org.apache.log4j.PatternLayout log4j.appender.stomp.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n log4j.logger.org.apache.activemq.transport.stomp=TRACE, stomp log4j.additivity.org.apache.activemq.transport.stomp=false # Enable these two lines and disable the above two if you want the frame IO ONLY (e.g., no heart beat messages, inactivity monitor etc). #log4j.logger.org.apache.activemq.transport.stomp.StompIO=TRACE, stomp #log4j.additivity.org.apache.activemq.transport.stomp.StompIO=false After this, all your Stomp packets will be logged to the Java APIFrom ActiveMQ 5.2: there is a simple Java Stomp API distributed with ActiveMQ. Note that this API is provided purely for testing purposes and you should always consider using standard JMS API from Java instead of this one. The following code snippet provides a simple example of using this API: StompConnection connection = new StompConnection(); connection.open("localhost", 61613); connection.connect("system", "manager"); StompFrame connect = connection.receive(); if(!connect.getAction().equals(Stomp.Responses.CONNECTED)) { throw new Exception ("Not connected"); } connection.begin("tx1"); connection.send("/queue/test", "message1", "tx1", null); connection.send("/queue/test", "message2", "tx1", null); connection.commit("tx1"); connection.subscribe("/queue/test", Subscribe.AckModeValues.CLIENT); connection.begin("tx2"); StompFrame message = connection.receive(); System.out.println(message.getBody()); connection.ack(message, "tx2"); message = connection.receive(); System.out.println(message.getBody()); connection.ack(message, "tx2"); connection.commit("tx2"); connection.disconnect(); This example is part of the standard ActiveMQ distribution. You can run it from the ant stomp Stomp Extensions for JMS Message SemanticsNote that STOMP is designed to be as simple as possible - so any scripting language/platform can message any other with minimal effort. STOMP allows pluggable headers on each request such as sending & receiving messages. ActiveMQ has several extensions to the Stomp protocol, so that JMS semantics can be supported by Stomp clients. An OpenWire JMS producer can send messages to a Stomp consumer, and a Stomp producer can send messages to an OpenWire JMS consumer. And Stomp to Stomp configurations, can use the richer JMS message control. STOMP supports the following standard JMS properties on
ActiveMQ Extensions to STOMPYou can add custom headers to STOMP commands to configure the ActiveMQ protocol. Here are some examples:
|