SF Console is a cross between a need to create some form of remote logging for APEX and an excuse to try and get my hands dirty with some technologies that I hadn’t tried before. In my head there are three parts to this story; the links to the other two are below and will become available once I’ve managed to actually get the code together to back up the thoughts!
- SF Console version 1: Just hacked together
- SF Console version 2: A node.js experiment
- SF Console version 3: Streamed
The initial pass of this project gave me the chance to play with websockets as I thought that they would be interesting and potentially have a great impact of how we interact with the web. And they are all those things, the trouble is they’re also a little disappointing but disappointing in a good way. I realise I’ve contradicted myself there so let me explain. Websockects work. And they work well. The implementation is baked into the browser and that just works and if you can get a well written server then that too will just work. Putting the two together is really really easy. And it’s that which is disappointing – I thought it would be a challenge and I like challenges. Having said that most of the world doesn’t and it’s for that reason that it’s disappointing in a good way… this stuff works and when stuff just works people tend to use it; it becomes a tool not an obstacle.
Anyway back to moving forwards… I mentioned in my previous post on this topic that I rushed together the “broker” (it’s in quotes because it’s not really a broker but it’s a handy description) part of the application using a C# solution and that I was hoping to change that later. Well, that’s where node.js comes into the picture. And not only node.js but node on Heroku – just to give it that SalesForce.com spin.
Once I’d got my head into the node.js space – thinking in an asynchronous fashion and trying to make sure I got my closures in the right places (I’m fairly sure I still haven’t got those right). I actually found that writing the code came fairly easily.
My first surprise was actually with the platform… node.js support on Heroku is a relatively new thing and the web sockets protocol is also fairly new: too new in Heroku’s eyes to be stable enough for their platform. Which is a shame as it meant I had to revert to some of the older techniques for holding a channel open to the client. Luckily I quickly came across the socket.io library which is frankly fantastic. It provides both server and client js implementations of a series of protocols for client-server js communication (including web sockets) and will graciously fail back until it finds an acceptable means of communication for the two ends of the channel. I would have made use of this library even if I was using web sockets so for me it was an obvious choice – just tweak the config and off we go.
There are a lot of frameworks and libraries available on node and they all make your life slightly easier – I decided to make use of the connect middleware framework as this provided me with a few bits and pieces that I saw no point in reinventing, namely; cookie parsing, POST body parsing, static content serving and a favicon server. This saved me from a bunch of work and from probably messing the solution up with my poor JS skills more than I already have. the connect middleware is fairly simple to use and although the documentation is lightweight it provides wnough to get you started, plus the source is always there if you get stuck. The one thing that I would mention is that if your writting your only handler to go in the middleware then make sure you accept the next parameter, not just req and res. More importantly make sure that if you don’t end the response you call next – otherwise everything will get lost, nothing else in the chain will get called and the server will never complete the response to the client.
Having just moaned about the tiredness of the SOAP protocol I’m now going to say that I again decided to make use of it to log into SalesForce rather than using OAuth. I do however have a justification. After the user has logged in I need to associate an OrgId with their connection so that I know to whom to forward the messages. The response from the SOAP login call on the partner WSDL gives me this information without me having to make another call. It just felt cleaner to do it this way. I’m sure there are a million other better ways to do it… but this is what I chose and why.
There’s not much else to say; the usr logs into SalesForce via the partner web service, the server stores their OrgId against their connection. SalesForce sends Outbound Messages to a fake SOAP endpoint on the node server, it responds with an Ack. The message is then parsed and sent to all connections that have the same OrgId as the incoming message. Job done.
The client remains pretty much the same as before the only real difference is to include a reference to the sokect.io client lib (which the server serves itself) and we’re all good to go.
All of this is now available in GitHub… it’s in two projects SF-Console and sf-console-node I’ll let you figure out what they are from their incredibly imaginative, albeit inconsistent, names. The projects are really not much more than a starting point for those that may be interested in the idea – for example I know there are still things missing and the testing hasn’t been all that extensive, especially around multiple orgs connecting to the same node.js endpoint. Feel free to rip off, laugh at, copy or contribute all I ask for is a little feedback: even laughter.
There’s a small issue with the HTTPS version of this at the moment… HTTP works though so if you’re brave go for it, otherwise wait for the update later.