sgentle/phantomjs-node — pull request #79 by orls (2013-05-19 17:44:55+00:00)
Title: Support Node 0.10, clustered usage, and a few missing features

This is a sizeable change, providing several different abilities...

Let me know if separate pull requsts are easier.

### Support Node 0.10

...by way of a **major version bump in dnode**. Dnode's API has changed dramatically in the versions since phantomjs-node was first written; it no longer uses socket.io for a start, doesn't allow binding in to an existing server as easily, etc, etc...

The reported issues with 0.10 (#74, #77) are due to a flaw in an old version of node-lazy, which is depended on by the old version of dnode that phantomjs-node was written against. There's no clean upgrade path to a newer dnode (and hence a newer node-lazy (in fact its gone totally)) without a change of this magnitude.

Since PhantomJS now supports (not sure since when) websocket connections from it's own javascript environment, there's no need for the arcane setup with the 'control' page, parsing alerted messages, etc. This simplifies the setup and the dependency tree greatly. The 'shim' script can open a socket connection directly to your app code, and talk using modern dnode.

Best of all, this doesn't change the API etc all all. Fewer dependencies, fewer bugs, better version support, and no end-user code change. Yay! (unless you're doing your own voodoo with the socket / control page, in which case, good luck -_-)

### Make port number configurable

This was the real blocker to cluster usage, because the previous code was assuming that `...someserver.listen()` would pick a random port: in cluster subprocesses, they [each get the same 'random' port](http://nodejs.org/docs/v0.10.7/api/cluster.html#cluster_how_it_works). This explains why [cluster usage is still not working](https://github.com/sgentle/phantomjs-node/issues/56#issuecomment-17857270) despite [a recent change](https://github.com/sgentle/phantomjs-node/issues/76).

Pass a port number in as the final arg to `create()`. You'll need to specify the phantom binary beforehand (see below for why, pass 'phantom' for default)

This allows you to do the following under clustered usage:

```javascript
var phantom = require('phantom');
var cluster = require('cluster');

var base_port = 12300;

phantom.create(
function(ph){

},
'phantom'
base_port + (cluster.isWorker ? cluster.worker.id : 0) // ta-da!
);
```

Ta-da! Each cluster worker gets an incremental port, but standalone use works fine too.

### Use your own PhantomJS binary

...by passing in a full path to the binary as an extra argument to `phantom.create()`, after the callback.

This allows use of [the phantomjs npm meta-package](https://npmjs.org/package/phantomjs), which eases deployment/setup/bootstrap for your app, by not needing phantomjs globally installed and allowing you to peg versions precisely, you just add it to package.json and `npm install`. To use it with this patch:

```javascript

var phantom = require('phantom'); // this library, the phantomjs 'bridge' code
var phantomjs = require('phantomjs'); // the npm metapackage, wrapping a 'blessed' binary. Aren't names fun?! (╯°□°）╯︵ ┻━┻

phantom.create(
function(ph) {
console.log('got a phantom handle', ph);
},
// here's the magic: use the path to the binary that the phantomjs package installed,
// somewhere inside your node_modules folder
phantomjs.path
);
```

This defaults to 'phantom' (i.e. whatever's on your system's PATH), which is all the previous impl did anyway.

### Expose Phantom's 'WebPage.close()' method

...for those who want to be neat and tidy :)

### Fire setContent() callback more appropriately

...for those who are paranoid about long page load times :)

Also calls the callback with the statusCode, in case that's useful.

----

## Using these patches now

Until this pull req is merged, the version is bumped, and it's published on npm – which might be a while since maintenance on this repo seems low – you can get the above features by pointing NPM directly at my fork: in your package.json, change the dependency to:

```json
"phantom": "git://github.com/orls/phantomjs-node.git#2d49873c"
```