BOSH is much more efficient, from server load’s point of view and traffic-wise. In this tutorial I set up Openfire XMPP server (which also provides the BOSH functionality) with JSJaC library as client, using Apache as web server on Ubuntu 10.04. Openfire has Debian package and as such, installation is fairly easy. Just download the package and install. After installation browse to port 9090 on the machine it was installed on, and from there it’s web-driven easy setup. If you choose to use MySQL as Openfire’s DB make sure to create dedicated database before (mysqladmin create).
After initial setup, I wasn’t able to login with the “admin” user. This post solved my problem, openfire.xml is located at ï»¿/etc/openfire (if you installed from package), you will need root privileges to edit it and then restart Openfire (sudo /etc/init.d/openfire restart). Other than that everything worked fine. Openfire server (as well as all major XMPP servers) provides the BOSH functionality, aka “HTTP Binding” aka “Connection Manager”. By default it listens on port 7070, with “/http-bind/” (the trailing slash is important).
To make sure it works (this is the part I couldn’t find anywhere, that’s why it took me long time to resolve all problems) I used “curl”, very handy tool (sudo apt-get install curl). To test the “BOSH server”:
# ï»¿curl -d “<body rid=’123456′ xmlns:xmpp=’urn:xmpp:xbosh’ />” http://localhost:7070/http-bind/
Switch “localhost” with your server name, notice the trailing slash. Expected result should look like:
<body xmlns="http://jabber.org/protocol/httpbind" xmlns:stream="http://etherx.jabber.org/streams" authid="2b10da3b" sid="2b10da3b" secure="true" requests="2" inactivity="30" polling="5" wait="60"><stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>CRAM-MD5</mechanism></mechanisms><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></stream:features></body>
Add to /etc/apache2/httpd.conf the following lines (root privileges needed):
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
Then, add to /etc/apache2/apache2.conf the following lines (root privileges needed):
ProxyPass /http-bind http://localhost:7070/http-bind/
ProxyPassReverse /http-bind http://localhost:7070/http-bind/
ProxyPass /http-binds http://localhost:7443/http-bind/
ProxyPassReverse /http-binds http://localhost:7443/http-bind/
Now restart the Apache (sudo /etc/init.d/apache2 restart) and make sure it starts properly. To verify the forwarding works, use the same curl method, this time as request to the Apache:
# ï»¿curl -d “<body rid=’123456′ xmlns:xmpp=’urn:xmpp:xbosh’ />” http://localhost/http-bind
The result should be the same as before. If it doesn’t work there is problem with the forwarding. Update: if you get “403 Forbidden” error from Apache, this may help (thanks Tristan). Once it is working, server side is ready. On the client (in my case JSJaC), you should specify to use BOSH/HTTP Bind “backend” (as opposed to “polling”). For “http bind” url just use “/http-bind” and everything should work. Notice that if you open the client locally on your desktop (not served by the Apache) it won’t work because of the “same origin policy” mentioned before.
I hope you find this tutorial useful, it sure could have helped me… 🙂
10 responses to “Setting up XMPP BOSH server”
[…] hold real tcp connections you need to cheat when doing jabber/xmpp. The hack in this case is called bosh (which is basically just binding over http). this binding lets you fake these long held tcp […]
Aha, the ‘same origin policy’ is the sneaky bitch. Good work.
there is error message “couldn’t connect to host”.
How to solve it?
When exactly are you getting this? sounds like either the service is not running or you try to connect to the wrong port
Quite strangely, I followed the instructions perfectly and am able to connect to my XMPP server using the IP I told it to bind to (my server has 3 IPs, one is HTTP, the next one is XMPP) and I also tell it to bind to 127.0.0.1 and localhost. Whenever I attempt to go to 247server.net/http-bind/ I get a 403. What could I be doing wrong?
Sounds like Apache is not configured correctly to forward /http-bind to the XMPP server. Make sure you have the trailing slash on the ProxyPass and ProxyPassReverse lines if you followed my method.
I’m pretty sure I have everything configured. My apache2.conf goes like this:
ProxyPass /http-bind http://126.96.36.199:7070/http-bind/
ProxyPassReverse /http-bind http://188.8.131.52:7070/http-bind/
ProxyPass /http-binds http://184.108.40.206:7443/http-bind/
ProxyPassReverse /http-binds http://220.127.116.11:7443/http-bind/
I also told Apache to load both of the modules you mentioned using a2enmod.
Apache’s error log says this:
[Sun May 22 14:13:36 2011] [error] [client 18.104.22.168] client denied by server configuration: proxy:http://22.214.171.124:7070/http-bind/
Well, obviously the problem relies in Apache configuration.
Have you looked at these (just came up on google):