This work is based on Hiram Chirino’s excellent library. It would be great if this “extended” version become part of that project too, but for now you can grab it from here.
While the original library is well written, there were few things that prevented me to use it in my project. I started by fixing those things, but then gone too far and now it is quite different from the original, so I’m putting it here.
Here is the list of the things that I have changed:
- Fixed some minor bugs – such as sending
ABORTmessage instead of
- Added failover transfer protocol support – This was my original motivation as I want to send messages from PHP to Java application that will use ActiveMQ high availability options (such as Master/Slave architecture of brokers).
The suggested solution is to run a local broker that will server as a proxy to the HA cluster. I wanted to avoid this “middle man” approach and send messages directly to the appropriate broker.
So I changed the connection routine and now instead of creating the connection with
$c = new StompConnection('s1.example.com', 61613);
you can use this construct:
$c = new StompConnection ('failover://(tcp://s1.example.com:61613,tcp://s2.example.com:61613) ?randomize=false');
consumer.phpexamples for more details.
Also, once connected if library detects connection break (while writing or reading) it will try to reconnect to another broker and proceed with its operation.
Please note, that not all functionality of the failover transport protocol is currently implemented. See “To do …” section for more details.
- Removed Socket functions usage – There is nothing wrong with these functions, but for them to be used PHP must be compiled with
--with-socketswitch which often is not the case. Also, there is no much real benefits over using
fread()so I think this will make this library usable in a broader range of environments.
- trigger_error() (instead of die()) – I have user
trigger_errorPHP function instead of
dieto log messages and report errors. In this way library will play much nicer with PHP applications.
As I said, my primary usage of this library will currently be to reliably send messages from PHP to Java. There was one interesting problem that I have encountered that I will document here.
In case that master broker dies, socket on the server goes into
FIN_WAIT_2. That is OK, but it leaves socket on the client (PHP) side in
CLOSE_WAIT state for a while. This means that next message sent from the same PHP script will be send as if nothing had happened and only while sending the following message PHP will trigger an error. Of course, this leads to message loss which is not acceptable. This is why I send an empty (
^@) message before any real message is sent.
I know that it is not a clean solution but it works. Any advice on this topic is more than welcome.
As I modified this library for my own purposes I didn’t polished its details for things that I won’t be using at this moment:
- As I don’t attend to read messages from PHP, I haven’t put much effort in this part of the library. It generally works (as in original but with reconnect functionality) but I noticed some strange things from time to time, so be sure to test it thoroughly before you use it in production. I’ll also try to find some time in the future to work on this
To do …
Some things that will be subject to more work in the future:
- Parse all failover transport URL parameters – Currently, there is only the difference whether you are using
randomizeparameter. The number of reconnection attempts is hardcoded to 10. I would like to support all parameters available.
- Test it more
- Test and work on message consumption – see “Known issues”
- JSON and MapMessges – I plan also to send a kind of maps from my PHP application. I think that the best way would be to use JSON format for coding and encoding. I’ll try to experiment with this in the coming days and let know the results. For starters, I’ll decode messages in my message listener, but maybe it would be a good idea to support this in the ActiveMQ Stomp implementation (message would be marked with special header). I think that JSON is the best solution, because it is simple and the there is a library available for almost any scripting language, so it can be quickly implemented in existing Stomp clients.
While this is not finished work, I hope that I have made this library more usable than it was. Any feedback is more than welcome.
Very nice. Outside related to your todo’s, one of the things I want to do for ActiveMQ 4.1 is provide pluggable handling of how JMS message types get mapped in and out of Stomp, the current system works, but is kind of weird (bytes message if a content-length is sent, otherwise a text message).
Yes, the current message type detection is weird indeed. I will start working today on the JSON encoding/decoding of messages (I’ll post it here when finished). Can you share at this point the mechanism that will be used for this message type mapping. I would like to make my current work compatible with the future versions of ActiveMQ. Also if you are interested, I would like to help you implement this functionality in ActiveMQ. So if you have some work in progress (or even just ideas how it should look like), please let me know.