Stomper
Author: Oisin Mulvihill
Introduction
This is a python client implementation of the STOMP protocol.
The client is attempting to be transport layer neutral. This module provides functions to create and parse STOMP messages in a programatic fashion. The messages can be easily generated and parsed, however its up to the user to do the sending and receiving. The STOMP protocol specification can be found here:
http://stomp.codehaus.org/Protocol/
I've looked at the stomp client by Jason R. Briggs. I've based some of the 'function to message' generation on how his client does it. The client can be found at the follow address however it isn't a dependancy.
http://www.briggs.net.nz/log/projects/stomppy
I now test using the basic MorbidQ broker http://www.morbidq.com/ which is easy-installable "easy_install morbid". MorbidQ uses stomper as a dependancy so it will be automatically downloaded and installed with MorbidQ.
You can still use alternative brokers such as ActiveMQ. The server runs in java, however its fairly standalone and easy to set up. The projects page is here http://activemq.apache.org/
Examples
Basic Usage
To see some basic code usage example see "example/stomper_usage.py". The unit test "tests/teststomper.py" illustrates how to use all aspects of the code.
Receive/Sender
The example "receiver.py" and "sender.py" show how messages and generated and then transmitted using the twisted framework. Other frameworks could be used instead. The examples also demonstrate the state machine I used to determine a response to received messages.
I've also included "stompbuffer-rx.py" and "stompbuffer-tx.py" as examples of using the new stompbuffer module contributed by Ricky Iacovou.
Version History
0.2.2
- OM: Applied patch from esteve.fernandez to resolve " Issue 4 : First Message not received" in the example code.
- OM: I've updated the examples to use twisted's line receiver and got it to "detect" complete stomp messages. The old example would not work if a large amount of data was streamed. In this case dataReceived would be called with all the chunks of a message. This means that it would not be correct for it to attempt to unpack and react until the whole message has been received. Using twisted's line receiver looking for the \x00 works like a charm for this.
- OM: This release integrates the bug fixes and the optional stompbuffer contributed by Ricky Iacovou
- RI: Removed the trailing '\n\n' inserted by Frame.pack(). I believe that adding this is incorrect, for the following reasons:
http://stomp.codehaus.org/Protocol gives the example: CONNECT login: <username> passcode:<passcode> ^@ and comments, "the body is empty in this case". This gives the impression that the body is *exactly* defined as "the bytes, if any, between the '\n\n' at the end of the header and the null byte". This works for both binary and ASCII payloads: if I want to send a string without a newline, I should be able to, in which case the body should look like: this is a string without a newline^@ ... and the receiver should deal with this. This impression is reinforced by the fact that ActiveMQ will complain if you supply a content-length header with any other byte count than that described above. I am also unsure about the newline after the null byte as nothing in the protocol says that there should be a newline after the null byte. Much of the code in StompBuffer actively expects it to be there, but I suspect that *relying* on a frame ending '\x00\n' may well limit compatibility. It's not an issue with Stomper-to-Stomper communication, of course, as the sender puts it, the receiver accepts it, and ActiveMQ happily sends it along.
- RI: StompBuffer has had a few fixes; most notably, a fix that prevents a content-length "header" in the body from being picked up and used (!). The biggest change is a new method, syncBuffer(), which allows a corrupted buffer to recover from the corruption. Note that I've never actually seen the buffer corruption when using Twisted, but the thought occurred to me that a single corrupt buffer could hang the entire message handling process.
- RI: Fixed the typo "NO_REPONSE_NEEDED". I've changed it to NO_RESPONSE_NEEDED, but kept the old variable for backwards compatibility.
- RI: I've modified the string format in send() to include the '\n\n' between the header and the body, which I think is missing (it currently has only one '\n').
- RI: Added CONNECTED to VALID_COMMANDS so syncBuffer() does not decide these messages are bogus.
- RI: Added new unit test file teststompbuffer which covers the new functionality.