Version 11 of Stomp

Updated 2013-05-19 11:35:50 by APN

STOMP stands for the Simple (or Streaming) Text Oriented Messaging Protocol. STOMP provides an interoperable wire format so that STOMP clients can communicate with any STOMP message broker to provide easy and widespread messaging interoperability among many languages, platforms and brokers.

STOMP is loosely modeled after the HTTP protocol, where "messages" will typically start with an uppercase command (like GET in HTTP), followed by a number of headers (format is similar) and possibly followed by a body. Messages are ended by ^@, i.e. the zero character, aka ASCII 0, '\0'. STOMP advocates utf-8 on the wire and provides mechanisms that keep the connection alive, if necessary, thus making sure routers do not close connections. The complete specification is rather short and specifically targets scripting languages.

As I (EF) needed to understand STOMP in a better way, and despite there was already an implementation available at [L1 ], I decided to start coding it from scratch again. The resulting library is in the half-bakery [L2 ]. For the time being, it only provides a STOMP client implementation. The implementation is almost complete, it is only missing support for transactions. However, I intend to code it all the way, resulting in a simple "broker" implementation, an implementation that would allow any Tcl application to implement a STOMP server.

My implementation differentiates itself from the other in the following ways:

  • It is coded in pure Tcl, without any object layer. It should even be running on oldish implementations of the language, i.e. 8.4 (not tested though).
  • It implements the heart-beating facilities as of the specification.
  • It handles automated reconnections, but also gentle disconnection, as of the specification.
  • It provides introspection facilities to be notified of the changes in connection state.
  • It supports receipts for messages.
  • Apart from a high-level interface to subscriptions, it also provides a lower-level interface to PUB/SUB mechanisms. This allows to provide full support for the different types of acknowledgements specified.
  • It provides an interface to low-level messaging on the wire.

The current implementation has had little testing, initial tests against the Apache Apollo broker have shown proper behaviour. Please send any positive or negative feedback to me on the usual channels.

The following script highlights some of the capabilities of the library.

package require stomp

proc received { cid rid } {
    puts "Server has received message, id: $rid"
}
 
proc incoming { msg } {
    puts "Incoming message: [::stomp::message::getCommand $msg]"
}

# Connect to broker (following is default admin user for Apollo)
set s [::stomp::connect -user admin -password password]

# Subscribe to a queue at the server and arrange to receive
# messages for that queue in the procedure called "incoming"
# We wait before the subscription because connecting to a server
# implies a handshake mechanism. Instead, we could use the
# introspection mechanisms provided by the -liveness option to
# ::stomp::connect
after 1000 ::stomp::subscribe $s /queue/a \
    -handler incoming

# Send a message to the same queue, meaning we'll receive it
# in the "incoming" procedure. Also make sure we'll receive
# a receipt for the message in the procedure "received"
after 2000 ::stomp::send $s /queue/a -body "Hello world" -receipt received

# Disconnect after a while, you might want to force disconnection from
# the web UI at the server to see what happens in the mean time.
after 60000 ::stomp::disconnect $s

# Live for ever..
vwait forever

APN Very much interested in this, the server side as well. So happens I was looking for a simple message broker implementation in script and your post showed up. Serendipity!

EF You are welcome, and please try it as it's really in its early days... :) As long as you're not too impatient, I hope to be able to finish up some initial version of the server within the next few weeks. It needs some refactoring, moving out most of the actual code to a ::stomp::client namespace so I can start having common procedures in ::stomp and start with a ::stomp::server.

APN Any thought of putting it in a public repository ? The half-bakery is not the most convenient for keeping track of changes.

APN Tried it (took an hour to set up Apollo thanks to spaces in the path to the JRE). Looks pretty good. Stopped and restarted Apollo and life went on without a hitch. Didn't see how to get the data of received message so directly accessed the ::stomp::message::msg_* array. Also binary data did not seem to get through so I'm not sure if the protocol does not support it or some options have to be set. Looks like a great start.