Stomp and JSON

As I said in the previous post, one of my main intentions is to use Stomp to send map messages from PHP to Java. So in this iteration, I have added support for JSON encoding/decoding of message content.

Before I dig deeper into new functionalities and changes, let me explain which JSON libraries (PHP and Java) I have used and why.

Dependencies

Even though since version 5.2.0, PHP has native support for JSON, I have used pure PHP implementation from Michal Migurski. I did this for only one reason: There is no any restriction to use it in PHP4.

For those interested in using PHP native JSON support in PHP5 or native C implementation by Omar Kilani, it should be easy to modify this work, since all JSON related code is encapsulated in one class (more about this later).

For current Java example, I have used JSON.simple toolkit. The only reason for this is that JSONObject inherits java.util.HashMap so it is much easier to process it in the client.

After this brief discussion, it’s time to focus on changes made to the original version of the library.

Changes

New classes

I’ve created three new classes:

  • StompMessage
  • BytesMessage
  • MapMessage

All this classes are inherited from basic StompFrame class and are used to encapsulate type-specific behavior.

StompMessage is representation of JMS TextMessage. The example of its usage could be:

$c->send("/queue/test", new StompMessage("test"));

Note that this is equivalent to the older syntax:

$c->send("/queue/test", "test")

So the usage of this class is not mandatory and it is here just for the library completeness.

BytesMessage is not tested in more details. The only difference between this class and StompMessage is that it sets content-length header. It should be tested more.

MapMessage is what this update is all about. Now you can easily create a MapMessage in the following manner:


$msg = new MapMessage(array("key1"=>"value1", "key2"=>"value2"));

$c->send("/queue/test", $msg);

It will be encoded in JSON format and sent as JMS TextMessage to the broker. As I saw on some mailing list discussion, it is advised to mark this kind of special encodings with amq-msg-type header so that it complies with future pluggable Stomp message handlers in ActiveMQ. So this class also set MapMessage value for this header.

Also, when you consume messages with this library, if amq-msg-type is found and has MapMessage value, message content will be decoded and MapMessage will be returned to the client.

Here's an example:


$message = $c->readFrame();

if (is_a($message, 'MapMessage')) {
  foreach($message->map as $key=>$value) {
    echo "$key => $value
"; } } else { print_r($message); }

Examples of working with map messages could be found in the producer_map.php and consumer_map.php.

Java client

I've created an example of Java message listener that consumes both JMS MapMessages and Stomp JSON messages.

Here's a snippet of code that shows how handling could be done:


Map data = new HashMap();
if (message instanceof TextMessage) {
  String type = message.getStringProperty("amq-msg-type");
  if (type != null && type.equals("MapMessage")) {
      data = (JSONObject)JSONValue.parse(((TextMessage)message).getText());
  } else {
      throw new Exception("Not valid JSON message");
  }
} else if (message instanceof MapMessage) {
  data = ((ActiveMQMapMessage)message).getContentMap();
} else {
  throw new Exception(message.getClass() + " is not valid type for this que");
}

The whole example could be found in the ClientReceiver.java file.
Of course, the next step would be to put this on the broker side, so that client gets an ordinary MapMessage. That's something I'll try to do next.

Message acknowledgment

While I was playing with message consumption I noticed that acknowledgment is a bit impractical to write:


  $id = $message->headers['message-id'];
  $c->ack($id);

so I have enabled an easier syntax:


  $c->ack($message);

Of course, the old style is still valid.

To do ...

  • Testing and finishing ByteMessages
  • Work on ActiveMQ pluggable handlers of Stomp messages

2 comments

Leave a Reply to Dejan Bosanac Cancel reply

Your email address will not be published. Required fields are marked *