Over the past several days (more than I would like to admit) I’ve been working on getting a system based off of Jetty and ActiveMQ to work out of the box for PHP developers. While “out of the box” isn’t quite true I have been able to get everything to work in a single downloadable container. It uses ActiveMQ as the messaging system, which also has a WebSocket listener. ActiveMQ also has a queue called “worker” which is used to send job queue requests to the queue. That queue has an HTTP camel component which listens on the queue and forwards the requests to an HTTP pool. Running the whole thing is a pre-configured Jetty server. Getting that set up takes a smidgen of work, but it’s not that hard. grep -R is your friend.
The example application is a chat application (of course), but it has some added functionality. You can create a pure WebSocket chat server quite easily, no PHP needed. But I wanted to include PHP functionality so what I did was make the (ugly) frontend push the chat message to the queue and the worker would do three things.
- Parse it for Markdown-based content
- Regex the output for URLs and send those URLs back to the queue
- When dequeued the URLs are parsed for a content snippet, title and an image URL. If those are found they are sent back to the frontend which then attaches the snip to the original message container.
It’s kind of a neat little setup. And, what’s cool about it, is if you change the document root for the website you can run a Magento instance out of it.
It is configured to run on port 8161.
There are a few things you are going to need to do to make it work.
First, make sure you have PHP-FPM running on port 9000.
Second, edit the etc/vhosts/localhost.xml file to change the document root for the web application in the download’s html directory.
Third, edit the html/WEB-INF/web.xml to change the document root in that file as well.
To run PHP in Jetty you need to have the WEB-INF/web.xml file in there. There is a configuration setting where the only path to change it is in that file. I spent, literally, days trying to get this to work without building my own into Jetty. I could have done that, but I wanted this to run as much out-of-the-box as possible. The setting is async-supported, in case you are wondering. There was a change in one of the Jetty versions where FastCGI went from announcing it supported async by default to saying it didn’t. And the only way to change that setting is in the WEB-INF setting.
The application, as noted before, is a simple chat application. You can have multiple people sharing the same chat window. Everyone can chat with everyone else. There is no concept of a room, this is a demo after all.
To make it work, go to either http://localhost:8161/ or http://localhost/ if you set up iptables to route to port 8161. From there the chat window will open and you can start typing. Note that I have not built anything resembling security into this application.
Some notes on the packages installed. The first is the eschrade/async_pack composer package. I have used only one component, the Stomp client. That client extends the Fusesource Stomp package. I needed to extend it because I was getting connection errors when creating the WebSocket connection and it’s easier to extend a package than to get a fix done… especially a fix that could break other adapters.
One note on how I do queuing. It is wrong. Horribly wrong. Don’t use it as an example. In the eschrade/async_pack I created a queue client/server model that can be used. But for a simple demo what I did was sufficient. Maybe when I get some free time I’ll make it better.
I hope you try it out and like it. I’ve been a little bit surprised by how much I’ve liked it despite the fact that I’m using it largely as a web server. Perhaps it’s because this approach opens up a world of opportunities with PHP developers that, beforehand, required a lot of infrastructure chicanery. This package has most of what I’ve wanted in an all-in-one PHP environment for almost a decade.