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
Where a can download the sources of StompMessage,BytesMessage,MapMessage?
Hi Maxwell,
all these classes are available in the Stomp.php file distributed in this archive. Alternatively, you can grab it from the subversion repository at http://code.google.com/p/stompcli/source
Luckily, all this will be committed to codehaus soon, so stay tuned.