Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>TL;DR</h2> <h3>DNode</h3> <ul> <li>provides RMI;</li> <li>remote functions can accept callbacks as arguments;</li> <li>which is nice, since it is fully asynchronous;</li> <li>runs stand-alone or through an existing http server;</li> <li>can have browser and Node clients;</li> <li>supports middleware, just like <code>connect</code>;</li> <li>has been around longer than NowJS.</li> </ul> <h3>NowJS</h3> <ul> <li>goes beyond just RMI and implements a "shared scope" API. <a href="http://www.quora.com/Dropbox/Why-is-Dropbox-more-popular-than-other-programs-with-similar-functionality/answer/Michael-Wolfe" rel="nofollow noreferrer">It's like Dropbox</a>, only with variables and functions instead of files;</li> <li>remote functions <strong>also accept callbacks</strong> (<a href="https://stackoverflow.com/questions/5317282/what-is-the-difference-between-dnode-and-nowjs/5332557#5332557">thanks to Sridatta and Eric from NowJS for the clarification</a>);</li> <li>depends on a listening http server to work;</li> <li>can only have browser clients;</li> <li>became public very recently;</li> <li>is somewhat buggy right now.</li> </ul> <h3>Conclusion</h3> <p>NowJS is more of a toy right now -- but keep a watch as it matures. For serious stuff, maybe go with DNode. For a more detailed review of these libraries, read along.</p> <h2>DNode</h2> <p>DNode provides a Remote Method Invocation framework. Both the client and server can expose functions to each other. </p> <pre><code>// On the server var server = DNode(function () { this.echo = function (message) { console.log(message) } }).listen(9999) // On the client dnode.connect(9999, function (server) { server.echo('Hello, world!') }) </code></pre> <p>The function that is passed to <code>DNode()</code> is a handler not unlike the one passed to <code>http.createServer</code>. It has two parameters: <code>client</code> can be used to access the functions exported by the client and <code>connection</code> can be used to handle connection-related events:</p> <pre><code>// On the server var server = DNode(function (client, connection) { this.echo = function (message) { console.log(message) connection.on('end', function () { console.log('The connection %s ended.', conn.id) }) } }).listen(9999) </code></pre> <p>The exported methods can be passed anything, including functions. They are properly wrapped as proxies by DNode and can be called back at the other endpoint. This is fundamental: DNode is fully asynchronous; it does not block while waiting for a remote method to return:</p> <pre><code>// A contrived example, of course. // On the server var server = DNode(function (client) { this.echo = function (message) { console.log(message) return 'Hello you too.' } }).listen(9999) // On the client dnode.connect(9999, function (server) { var ret = server.echo('Hello, world!') console.log(ret) // This won't work }) </code></pre> <p>Callbacks must be passed around in order to receive responses from the other endpoint. Complicated conversations can become unreadable quite fast. <a href="https://stackoverflow.com/questions/5265743/node-js-what-techniques-are-there-for-writing-clean-simple-callback-code">This question</a> discusses possible solutions for this problem.</p> <pre><code>// On the server var server = DNode(function (client, callback) { this.echo = function (message, callback) { console.log(message) callback('Hello you too.') } this.hello = function (callback) { callback('Hello, world!') } }).listen(9999) // On the client dnode.connect(9999, function (server) { server.echo("I can't have enough nesting with DNode!", function (response) { console.log(response) server.hello(function (greeting) { console.log(greeting) }) }) }) </code></pre> <p>The DNode client can be a script running inside a Node instance or can be embedded inside a webpage. In this case, it will only connect to the server that served the webpage. <a href="http://senchalabs.github.com/connect/" rel="nofollow noreferrer">Connect</a> is of great assistance in this case. This scenario was tested with all modern browsers and with Internet Explorer 5.5 and 7.</p> <p>DNode was started less than a year ago, on June 2010. It's as mature as a Node library can be. In my tests, I found no obvious issues.</p> <h2>NowJS</h2> <p>NowJS provides a kind of magic API that borders on being cute. The server has an <code>everyone.now</code> scope. Everything that is put inside <code>everyone.now</code> becomes visible to every client through their <code>now</code> scope.</p> <p>This code, on the server, will share an <code>echo</code> function with every client that writes a message to the server console:</p> <pre><code>// Server-side: everyone.now.echo = function (message) { console.log(message) } // So, on the client, one can write: now.echo('This will be printed on the server console.') </code></pre> <p>When a server-side "shared" function runs, <code>this</code> will have a <code>now</code> attribute that is specific to the client that made that call.</p> <pre><code>// Client-side now.receiveResponse = function (response) { console.log('The server said: %s') } // We just touched "now" above and it must be synchronized // with the server. Will things happen as we expect? Since // the code is not multithreaded and NowJS talks through TCP, // the synchronizing message will get to the server first. // I still feel nervous about it, though. now.echo('This will be printed on the server console.') // Server-side: everyone.now.echo = function (message) { console.log(message) this.now.receiveResponse('Thank you for using the "echo" service.') } </code></pre> <p>Functions in NowJS can have return values. To get them, a callback must be passed:</p> <pre><code>// On the client now.twice(10, function (r) { console.log(r) } // On the server everyone.now.twice = function(n) { return 2 * n } </code></pre> <p>This has an implication if you want to pass a callback as an honest argument (not to collect a return value) -- one must always pass the return value collector, or NowJS may get confused. According to the developers, this way of retrieving the return value with an implicit callback will probably change in the future:</p> <pre><code>// On the client now.crunchSomeNumbers('compute-primes', /* This will be called when our prime numbers are ready to be used. */ function (data) { /* process the data */ }, /* This will be called when the server function returns. Even if we didn't care about our place in the queue, we'd have to add at least an empty function. */ function (queueLength) { alert('You are number ' + queueLength + ' on the queue.') } ) // On the server everyone.now.crunchSomeNumbers = function(task, dataCallback) { superComputer.enqueueTask(task, dataCallback) return superComputer.queueLength } </code></pre> <p>And this is it for the NowJS API. Well, actually there are 3 more functions that can be used to detect client connection and disconnection. I don't know why they didn't expose these features using <code>EventEmitter</code>, though.</p> <p>Unlike DNode, NowJS requires that the client be a script running inside a web browser. The page containing the script must be served by the same Node that is running the server.</p> <p>On the server side, NowJS also needs an http server listening. It must be passed when initializing NowJS:</p> <pre><code>var server = http.createServer(function (req, response) { fs.readFile(__dirname + '/now-client.html', function (err, data) { response.writeHead(200, {'Content-Type':'text/html'}) response.write(data) response.end() }) }) server.listen(8080) var everyone = now.initialize(server) </code></pre> <p>NowJS first commit is from a couple weeks ago (Mar 2011). As such, expect it to be buggy. I found <a href="https://github.com/Flotype/now/pull/9" rel="nofollow noreferrer">issues</a> myself while writing this answer. Also expect its API to change a lot. </p> <p>On the positive side, the developers are very accessible -- Eric even guided me to making callbacks work. The source code is not documented, but is fortunately simple and short and the user guide and examples are enough to get one started.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload