spacer

Updates from the NowJS team. Back to nowjs.com

Running NowJS natively on Windows

  • Edit
  • Delete
  • Tags
  • Autopost

Node.js v0.6.0 marked the first stable release of a native Windows build of Node.js, so for all the Windows users out there, Node in Cygwin should be a thing of the past!

NowJS on Windows

  1. Install node.exe and NPM for Windows and make sure all your paths are correct
  2. Install Microsoft Visual C++ Runtime (4.8 MB)
  3. Download the NowJS Windows branch zip or `git clone git://github.com/Flotype/now.git` and `git checkout windows`
  4. Rename `Flotype-now-XXXXXX` to `now` and put that in your node_modules folder

Congrats! You should now be able to `require('now')` from your app as long as the node_modules folder is in the path.

What's different in the NowJS Windows branch?

The only difference is in proxy.js, insteading of `require('node-proxy')` we `require('../bin/proxy.node')`

proxy.node is the compiled Windows binary of the node-proxy module and included as part of the Windows branch of NowJS.

Why has it taken so long to get NowJS working on Windows native?

In order to provide the `now` namespace functionality, we use the node-proxy plugin. Unfortunately node-proxy is a C++ V8 extension and thus requires compilation. With the release of Node v0.6.0, the toolchain for native module compilation for Windows was undocumented. This meant that we weren't able to compile the node-proxy dependency for NowJS. Several workarounds were proposed including using native harmony proxies found in current V8 builds (when run with --harmony_proxies flag). Unfortunately the current V8 implementation seems to contain a bug preventing correctly triggering setters when dynamic properties names are given (See code.google.com/p/v8/issues/detail?id=1543#c10). Eventually we settled on compiling node-proxy in Visual C++ and distributing that. 

Happy hacking!

Posted by Eric Zhang spacer

Why We Threw out All Our Code (And Why You Should Too)

  • Edit
  • Delete
  • Tags
  • Autopost

This past week, we proudly released NowJS v0.7. This version is the most stable and performant version of NowJS to date. It's managed to survive our vicious benchmarking tools and our ridiculously comprehensive test cases. But our greatest accomplishment with this release is that every single line of code is brand new.

In a matter of minutes, we decided to scrap 3 months of work and rewrite our architecture. No file, function or concept was left unquestioned. What inspired this iconoclastic frenzy? Here's why we threw out all our code:

1. Optimizing for real-world usage

When we started working on NowJS, we knew what we wanted the software to do. But there was no way of telling how people would use it and how it would perform in these scenarios. With v0.7, we optimized and made tradeoffs based on the data we collected from real-world usage.  It turns out that the vast majority of usage was for RPC and the occasional syncing of very simple variables. We reduced code complexity by not worrying too much about syncing complex nested/circular structures, and optimized the remote procedure calls process to be as close to constant time as possible.

2. Perfect opportunity to future-proof

Over time, we became much better at anticipating the type of features we were going to add to the library. This meant that we weren't shoehorning functionality onto a codebase that was never designed for it in the first place.  No longer were we wrestling with absurdly complex data structures and the equivalently insane functions needed to manipulate them. We eliminated the need for cryptic utility functions like "mapAndMergeFunctionsInScopesHelper". After the complete rewrite, features that we indefinitely put off took mere minutes to implement. 

3. Sunk costs and egos get in the way of good software

Our job as developers is to provide the best library so that you can write high-performance realtime web applications easily. We could have defended our code just because we worked hard on it for months. But accepting the large upfront cost of a rewrite meant that we would save on development time in the future and also provide a better product to our users.

So take a good look at your own codebase. Does it frustrate you when you try to add new features? Are you smarter now than when you first wrote it? If so, then perhaps it's time to dump it.

P.S. Check out NowJS v0.7 . It's rock solid and super-optimized for the best real-time RPC experience.

 

Posted by Sridatta Thatipamala spacer

NowJS and Security

  • Edit
  • Delete
  • Tags
  • Autopost

Security is a large issue when dealing with realtime applications, especially when there is bidirectional server-client communication and even more so with client-server-client interaction. It becomes an even larger concern in a project such as NowJS that synchronizes state between the server and clients.

A common misconception is that NowJS actually sends functions over the wire as part of the scope-synchronization process. This does not happen. Here's a high-level overview of how we handle remote procedure calling (RPC): when the client sends his scope to the server (and vice versa), instead of actually transmitting the body of any functions, he sends a serialized form of the function indicating only where the function is located within his now namespace. On the server, this serialized form is translated into a wrapper function whose sole function is to ask the client to execute the original function with the arguments passed in to this wrapper function.

What this means for the developer is that functions are only executed where they were created. Any given user can't do anything to other users that the server hasn't explicitly specified he can do. Furthermore, since the bodies of functions are not actually transmitted over the wire, the clients never see the actual serverside code that's running -- we provide, as one particular user in the IRC channel put it, "javascript IP protection".

The next concern individuals have regarding the shared namespace problem is that a malicious user might attempt to alter other users' now namespaces. The only way a user can do this is if a server-side function is provided to allow him to do so -- the server actually keeps track of all users' individual now namespaces, and as with Dropbox, a user's changes to his own now namespace will trigger an update in the server-side copy, and vice versa. For developers who want absolute control, the client's power can be restricted further, as changes to the client-side now namespace will be ignored if the clientWrite flag is set as false in the configuration options passed when initializing NowJS.

NowJS 0.7 supports passing in an HTTPS server upon initialization. No additional configuration is required.

Note that NowJS does not deal with preventing cross-site scripting (XSS) attacks; that is beyond the scope of this framework. If you're really worried about XSS, just add a thin layer of protection in your client code with

msg = $('<div/>').text(msg).html()

before inserting any arbitrary text into the document as HTML.

As always, let us know what you think in the comments below, and in our IRC channel #nowjs on irc.freenode.net

Posted by Steve Wang spacer

NowJS and Reconnects

  • Edit
  • Delete
  • Tags
  • Autopost

This particular feature has been highly anticipated by the NowJS community for some time. With the switch to Socket.IO 0.6.18, which now has built-in support for socket reconnecting, implementation of this feature was actually quite doable. We've tested with both simulated server downtime and client network issues, and it's worked satisfactorily. Several minor changes were necessary to support this feature in Now -- nothing that actually affects the API for developers using this tool; just a few changes to how things work in the backend.

Several disclaimers to make about Now and the general state of reconnects: first of all, it's not possible to preserve the client's session ID without forking Socket.IO. I have it from one of the Socket.IO folks that 0.7 will make everything public, including generateSessionId(), so when we bridge over to that version (we'll have to make sure that nothing breaks -- we've been developing a test suite, so that should hopefully ease the transition), this may change.

Additionally, client groups are not preserved across reconnects. One way to handle this would be to have the client know which groups he's in, and then send this information when the socket's reconnect event is triggered.

Note that client scopes, however, are preserved, so in the multiroom chat example, for instance, a reconnecting user originally in room 3 will be treated as if he's in room 1, but he'll still have the same name.

And now, the code.

The first block of code, pulled from handleDisconnection(), is as follows:

// y-combinator trick
(function (y) { 
  y(now, y, [now]); 
})(function (obj, fn, seen) { 
  for (var i in obj) { 
    if (obj[i] && seen.indexOf(obj[i]) === -1 && 
        typeof obj[i] === 'object' && obj[i] != document) { 
      seen[seen.length] = obj[i]; 
      fn(obj[i], fn, seen); 
    } 
    else if (typeof obj[i] === 'function' && obj[i].remote) { 
      delete obj[i]; 
    } 
  } 
});

I've omitted the tiny portion from constructRemoteFunction() where I tagged all remote functions as such. Essentially, this snippet runs through the now object and deletes all remote functions -- if this is not done, then upon reconnecting, the user will find himself running into infinite recursion -- when re-establishing the connection, since the client transmits his scope first, the server-side function will be redefined to call the client-side function, which simply calls the server-side function.

About the actual code: I figured it would be amusing to use the y-combinator trick instead of conventional methods which involve binding values to variables, especially since Flotype (the company behind NowJS) is a YC-funded company. Plus, it's just an awesome concept.

The other snippet, pulled from handleNewConnection(), is both straightforward and standard:

if (client.handled) return;
client.handled = true;

Since the rest of the function involves attaching function listeners, this ensures that these listeners are only attached once.

Well, that's that. Let us know what you think in the comments below, and in our IRC channel #nowjs on irc.freenode.net

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.