Monday, October 21, 2013

CandyJS and OpenFire configuration hell

CandyJS and OpenFire configuration hell

In my last post I got a web based client up and running with facebook chat. This used a BOSH server called punjab. This service acts as a proxy to the actual XMPP server for a web based client. This is required since we lack implementation details for the protocol at the browser level.

When riding on top of facebook chat you quickly realize that there are a number of limitations to 3rd party client. The largest one in my opinion been the lack of group chat support. If you to have been thwarted by this lack of support you can help by directing your request for group support in the API to the Facebook XMPP Developer Relations.

To build in our own support for this we will now need to host our own XMPP server. This is what the following article deals with... all the problems I had one a windows server.

First off ... given the choice I would implement the following on a linux based platform.. but this document may prove useful to someone in either case.

Choose your XMPP server I went and downloaded openfire, and open source apache licensed server. On windows this was an exe installer and a real breeze to install. Once installed you can login via a browser http://localhost:9000 and view / admin the settings.

The first thing that threw me a bit was not knowing that BOSH is integrated right into the openfire server. I originally though that I might have to use my punjab service to form a connection to openfire as well. This is wrong... your BOSH openfire service should be enabled and running on port 7070.

Now that we have our XMPP server up and running we will need to create a test client to connect to it. For me I choose to go with candyjs.

Configure Candy - So download and extract the candy files and example... looking at the documentation I did a configuration like the following.


Candy.init("http://localhost:7070/http-bind", {
  core: {
       debug: true,
       autojoin: ['name@conference.yourdomain.com']
   },
   view: { resources: '/assets/res/candy/' }
});

Candy.Core.connect('user@yourdomain.com','password');


I am developing my web framework in Scala using Play Framework... which like any development server runs on some higher port number (ex: 9000).
This gave me CORS errors saying that my server running on port 9000 is unable to communicate with the openfire server. No problem I rember seeing server settings in openfire to configure CORS. As it turns out I already had the domain set to properly. I tried a number of things to get this working but it always seemed to fail. No problem candy had provided documentation on HTTP Procy Configuration.

Proxy Setup - First thing I tried to do was to configure IIS using the URL rewrite module. This got me to a place of frustration as the "test" methods they provide claimed that it was working while I was unable to get the URL rewrite to perform in my browser.

Rather the fight with M$ I decided to just run the simple node.js proxy. But first off needed to shut down IIS. Going into the services tab a stoping the "World Wide Web Publishing" service should have been all that I need to do... but I failed to free up port 80. What made it worse was that `netstat -a -b -n` refused to tell me the process id that was bound to the port (as if this somehow provides a layer of protection?). With a bit more digging I wound that I also needed to shut down a service called "Web Deployment Agent". This did the job and freed up port 80.

Node.js config - now that I could bind node to port 80 I should have been off to the races, and indeed it looked that way for a while. I created the service as instructed on the candy HTTP Proxy Configuration

var http = require('http');
 
http.createServer(function(request, response) { 

 if(request.url === '/http-bind/') {
  var proxy_request = http.request({
   host: 'yourhost.com',
   port: 5280,
   path: '/http-bind/',
   method: request.method
  });
  
  proxy_request.on('response', function(proxy_response) {
   proxy_response.on('data', function(chunk) {
    response.write(chunk, 'binary');
   });   
   proxy_request.on('end', function() {
    response.end();
   });
   response.writeHead(proxy_response.statusCode, proxy_response.headers);
  });
  
  request.on('data', function(chunk) {
   proxy_request.write(chunk, 'binary');
  });
  request.on('end', function() {
   proxy_request.end();
  });
 }
 
}).listen(80);

So now my candy js configuration had the simple connection like this

Candy.init("http://localhost:7070/http-bind/", ...


Things seemed to be good on first request to the service and then hang on any further requests... grrrr!
Again after digging around I found a better way to implement the node.js proxy service using nodejitsu node-http-proxy


npm install http=proxy


Since I did not care about routing my request... I just wanted to test if this would work.. I wrote the simplest proxy I could think of.

var http = require('http'),
    httpProxy = require('http-proxy');
//
// Create your proxy server
//
httpProxy.createServer(7070, 'localhost').listen(80);


This now finally worked and candy connected properly to openfire.
This is a quick and dirty approach to getting things up and running... but I hope this helps someone else navigate around some of the bs involved and will allow you to get right to the fun stuff... coding.

No comments:

Post a Comment