Dan York

Just a guy in Vermont trying to connect all the dots...

Author's posts

Slides: Using Node.js in a production setting

Interesting set of slides around using Node.js in a production setting – and the choices these folks made around the technology stack they used:

How to use Node.js with IPv6

It turns out to be ridiculously simple. After my testing yesterday, I learned via a comment from Ryan Dahl, that:

all you do is have your Node.js app listen on the IPv6 address.

That’s it.

UPDATE 28 Jul 2014 – As a result of a Reddit thread I’ve seen traffic to this post.  Please do note that I wrote this post in early 2011 when I was experimenting with Node.js.  I’ve not kept up with the state of Node.js and so 3 years later there may be new or better ways to do what I’ve listed here.  Also, please see the comment from Simon Vetter indicating that you don’t need to start up two servers if you simply use “::” as the address. At some point I need to verify that and then update this post.

In a typical application using, say, the “http” module, you will have a line somewhere that says something like:

[js]
server.listen(80);
[/js]

This will bind to your default network interface and address, which, for pretty much all of us, will be our IPv4 address.

To bind to an IPv6 address, you just need to supply the address as an argument to listen(). For example:

[js]
server.listen(80, "2001:db8:1111:2222:3333::51"]
[/js]

So a very basic Node.js app using IPv6 would look like this:

[js]
var http = require(‘http’);

var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type":"text/plain"});
response.end ("Hello World!n");
console.log("Got a connection");
});

server.listen(80, "2001:db8:1111:2222:3333::51");

console.log("Server running on localhost at port 80");
[/js]

Note that as a Node.js app like this will only bind to a single interface and address, this app only listens on the IPv6 address and not on the IPv4 address. To make the app work on both the IPv4 and IPv6 addresses, I need to refactor it a bit into a function that is then called by two different servers that attach to the two network interfaces:

[js]
var http = require(‘http’);

var handler = function (request, response) {
response.writeHead(200, {"Content-Type":"text/plain"});
response.end ("Hello World!n");
console.log("Got a connection");
};

var server6= http.createServer();
server6.addListener("request",handler);
server6.listen(80,"2001:db8:1111:2222:3333::51");

var server= http.createServer();
server.addListener("request",handler);
server.listen(80,"192.0.2.23");

console.log("Server running on localhost at port 80");
[/js]

With that in place, it’s now answering on both the IPv4 and IPv6 addresses.

Now this is for the Node.js base modules… other modules may or may not “just work” for IPv6, too, depending upon what they rely on underneath. Regardless, it’s rather cool that it works so easily on IPv6. Kudos to the Node.js team for making it so simple!

Testing Node.js With IPv6 – First Step, Does It Work?

Given all the writing I’ve been doing lately about IPv6 and about Node.js, it was only natural for me to try combining them. I pay for a VPS over at RapidXen and upon request they will provide you with an IPv6 address block (for free). So I’ve been using it as a base for my IPv6 experiments.

I should note that my home network is set up with IPv6 via a IPv6-to-IPv4 tunnel from Tunnelbroker.net. I previously wrote up how I configured IPv6 this way using an Apple Time Capsule WiFi access point

Testing Apache First

After using IPv6-test.com to verify that I have HTTP connectivity over IPv6 from my system at home, I tested connectivity to my VPS running a stock CentOS 5.5 Apache server. Here was the IPv4 result (and yes, I cover up IP addresses… a certain degree of paranoia comes with the territory of being in the security space):

apachev4.jpg

Here was the same result with IPv6:

apacheipv6.jpg

(If you aren’t familiar with using IPv6 addresses in web browsers, you just enclose the IPv6 address in square brackets. The specific browser I’m using is Google Chrome on a Mac, but this should work in all browsers.)

Testing Node.js

The next step was to shut down Apache and start up Node.js. For this experiment, I’m purely using the HTTP module in Node.js and not getting into any of the frameworks. Here’s the very basic code I’m using (also on Github):

[js]
var http = require(‘http’);

var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type":"text/plain"});
response.end ("Hello World!n");
console.log("Got a connection");
});

server.listen(80);

console.log("Server running on localhost at port 80");
[/js]

After firing it up, connecting to the site via IPv4 was no problem:

nodejsipv4.jpg

And this is shown in the console:

bash-3.2# node httpsample.js
Server running on localhost at port 80
Got a connection
Got a connection

Next I tried the IPv6 connection:

nodeipv6.jpg

Oops. Predictably, the console log also did not show a new connection. I duplicated the test to make sure there wasn’t anything else funky going on, but had the same issue. Node.js wasn’t accepting HTTP connections via IPv6.

UPDATE: See below for the answer…

Testing the ‘net’ module

I was curious to see if the issue might be with the “http” module or if it was a broader issue. So I fired up a really basic TCP server example:

[js]
var net = require("net");

var s = net.createServer( function(c) {
c.addListener("connect", function () {
console.log("Connection from " + c.remoteAddress);
c.end("Hello Worldn");
});
});

s.listen(8000);

console.log("TCP server running on port 8000")
[/js]

From my Mac, I then tried connecting via IPv4 and IPv6:

$ telnet 69.xxx.xxx.xxx 8000
Trying 69.xxx.xxx.xxx...
Connected to rapidxen.net.
Escape character is '^]'.
Hello World
Connection closed by foreign host.

$ telnet -6 2607:xxxx:xxxx:xxxx::2 8000
Trying 2607:xxxx:xxxx:xxxx::2...
telnet: connect to address 2607:xxxx:xxxx:xxxx::2: Connection refused
telnet: Unable to connect to remote host
$

and found that IPv6 connectivity wasn’t supported in the “net” module.

Just to verify my testing method, I restarted Apache on the VPS box and used the same “telnet -6” command to hit port 80 on the box. I was able to connect and issue HTTP commands without a problem.

In the end…

So it would seem that Node.js doesn’t work with IPv6, which is not terribly surprising given that (Node.js founder) Ryan Dahl indicated in the #node.js IRC chat yesterday that basically no IPv6 testing had been done. Looking in the Node.js ChangeLog, IPv6 support was added in some form back in June 2009:

2009.06.18, Version 0.0.5, 3a2b41de74b6c343b8464a68eff04c4bfd9aebea

Support for IPv6

But without looking at code diffs, it’s not clear to me what exactly was changed to support IPv6.

The next step is obviously to start digging around in code… given that I’m picturing it as a bigger task, I’m not sure when I’ll get the chance to do, but it would be a good excuse to take a look inside the Node.js code.

In the meantime, if anyone else reading this has some Node.js modules they’d like me to test with IPv6, or other ideas around this, I’m glad to help. Just drop me a note or hit me on Twitter.

THE ANSWER

UPDATE:The answer that I couldn’t find anywhere online came in a comment to this post from none other than Ryan Dahl… Node.js DOES work with IPv6, provided you give it the address!

All I had to do to make the original code work with IPv6 was add the IPv6 address to the “.listen(80)”, like this:

[js]
var http = require(‘http’);

var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type":"text/plain"});
response.end ("Hello World!n");
console.log("Got a connection");
});

server.listen(80, "2607:xxxx:xxxx:xxxx::2");

console.log("Server running on localhost at port 80");
[/js]

But of course this only listens on the IPv6 address and not on the IPv4 address, so I needed to refactor the code a bit and run two servers:

[js]
var http = require(‘http’);

var handler = function (request, response) {
response.writeHead(200, {"Content-Type":"text/plain"});
response.end ("Hello World!n");
console.log("Got a connection");
};

var server6= http.createServer();
server6.addListener("request",handler);
server6.listen(80,"2607:xxxx:xxxx:xxxx::2");

var server= http.createServer();
server.addListener("request",handler);
server.listen(80,"69.xxx.xxx.xxx&");

console.log("Server running on localhost at port 80");
[/js]

With that in place, it’s now answering on both the IPv4 and IPv6 addresses!

Many thanks, Ryan, for the answer!

Want The Scoop on Node.js? Listen to Herding Code 102!

herdingcode.jpgWant to understand more about this Node.js thing I’ve been writing about here? Want to learn why people are raving about it? What the community is all about? What you can do with it?

If so, you can head on over and listen to episode 102 of the Herding Code podcast. The Herding Code hosts interviewed Tim Caswell who runs the great How To Node website full of info that can help you get started and learn more about Node.js. The podcast, which runs about 50 minutes, gives some great background to Node.js, explains how it works, discusses some of the many modules used with Node.js, how Node.js is different from other languages… and so much more.

Whether you are just starting with Node.js or have been using it for quite some time, I think you’ll find this interview quite useful and interesting.

Cool stuff…

NodeFu – Free Hosting of Your Node.JS Apps In The Cloud!

NodeFu.jpgHave you been experimenting with Node.JS (as I have) and wished you had a place to host your Node.js apps? If so, you may want to check out NodeFu.com, a new hosting service that just launched today.

Created by my friend and co-worker Chris Matthieu out of frustration with not getting invites for some of the other new Node.js hosting services, NodeFu is hosted up in Amazon EC2 and currently offers free hosting of Node.js apps to anyone interested.

Getting Started

As shown on the NodeFu home page, the process of using NodeFu is fairly straightforward. You request a coupon (an invite) via a commandline curl:

curl -X POST -d "email=your_address@example.com" http://nodefu.com/coupon

When you get an email confirming your invite, you can register an account, provide our ssh public key, etc.

From then on out all deployments happen purely through git commands. You start out by registering a new NodeFu application via another command-line curl command:

curl -X POST -u "testuser:123" -d "appname=myapp&start=hello.js" http://api.nodefu.com/app

NodeFu will respond with some JSON that includes the port number your app will run on and the name of the git repo you will push to. You then just do two git commands:

git remote add nodefu the_url_returned_by_our_api
git push nodefu master

And your NodeFu app will be live at http://appname.nodefu.com. As you work on your app, you just do more commits to your local git repo and then do a “git push nodefu master” when you want to update the live app. Once you push to NodeFu, your app should automagically be updated.

A Very Basic Example

You can see NodeFu in action in a VERY basic form at:

http://dany2.nodefu.com

As I write this post today, that app is literally a super basic “Hello, World” Node.js app. The code is visible up on GitHub at https://github.com/danyork/nodefu-dany2 and hopefully in the next bit I’ll have a chance to turn it into something a bit more involved.

Building Voice and SMS Apps with NodeFu

I’ve also created a Tropo app at http://tropohello.nodefu.com which uses the Tropo WebAPI library for Node.js to return JSON to Tropo.com where you can connect to the app using voice, SMS, IM or Twitter. Right now I only have voice and SMS wired up, but you can try out the app at any of these numbers:

Voice & SMS Messaging: +1-850-462-8472
Skype Voice: +990009369991478810
SIP Voice: sip:9991478810@sip.tropo.com
INum Voice: +883510001827346

Tropo is providing the voice and SMS connectivity and then communicating with my app running over on NodeFu.com. Pretty cool stuff!

Learning More and Trying It Out

You can just go to NodeFu.com to learn more and ask for an invite. Chris has invited 50 people in so far and plans to be giving out more invites over the next few days. It’s notable that Chris has open-sourced the entire codebase for NodeFu, so anyone else could really just download Chris’ code and set themselves up with their own NodeFu-like site:

https://github.com/chrismatthieu/nodefu

Here’s a video explaining what Chris is trying to do:

Other Options

I should note that Chris isn’t alone in coming up with a service like this. The comments to the Hacker News story about Chris’ site (and also the Mashable story) show a range of other Node.js hosting options, including:

… and a couple of others were listed, too, but they seem to offer other forms of hosted JavaScript versus Node.JS hosting.

The key point of all of this is that for those of us experimenting with Node.JS, this is truly a wonderful time to be trying it out, because we now have so many options before us!

Running (on a treadmill) with Node.js

What I didn’t say in my last post about the NodeTuts video tutorials was how I have been watching the episodes. Yes, indeed, I’ve been watching them while running or walking on our treadmil… this morning I ran 4 miles and went through two of the Node Tuts episodes (11 and 12):

nodejsontreadmill.jpg

As you can see, I just place the iPad in the tray of the treadmill[1] and then have a 1/8″ audio cable going from the iPad audio output to the audio jack on the treadmill which then sends the audio out the treadmill’s speakers. It’s an okay setup, although the iPad screen is off-center and down a bit. You don’t see it in a picture, but we have a 27″ flat panel TV to the left of the treadmill. I may at some point get the VGA connector for my iPad which would let me then output the video to that TV and gain the use of its speakers as well as the larger screen. But so far it’s working well.

Fun, fun, fun…

[1] The treadmill is a new NordicTrack c900 for those wondering.

Node Tuts – a video podcast tutorial on learning Node.js

In my continued interest to learn more about Node.js, I was recently pointed to an enjoyable set of video podcasts called “Node Tuts” and available at:

http://nodetuts.com

In each episode, host Pedro Teixeira walks you through how to perform some task using Node.js. He uses a combination of the command line, TextMate (to view the code) and his web browser. I have only started working through the series, but so far I have already picked up a few tips and learned about a few new modules to check out.

These episodes are recordings of Pedro hacking away and do include mistakes he makes (and corrects). This actually was okay because it helped me check my own knowledge. There was one show where I thought “he didn’t declare that module” and sure enough he had to go back and correct that. The rawness of the recording, though, was helpful in understanding how you could debug code in Node.js.

I do also like that each episode builds on the previous one (so far). It provides a useful way to expand your knowledge based on what you just learned.

As I mentioned, I am only starting to work through the recordings, but so far I have found them quite helpful!

Git Immersion – A New Tutorial Site About Git

Git Immersion - Brought to you by EdgeCase.jpgWant to learn more about the Git version control system? I recently was pointed to a new site called Git Immersion that provides some great, simple, step-by-step tutorials to get you started with using git. I love the premise:

Git Immersion is a guided tour that walks through the fundamentals of Git, inspired by the premise that to know a thing is to do it.

For those of you wanting to learn more about git, Git Immersion s definitely worth a walkthrough…

Setting Up a PyPI Account – And Uploading the Tropo WebAPI Library

Python logoIt’s funny… I’ve been writing small python programs for 10 or 15 years now (makefaq being perhaps the one most widely used), but in all that time, I had never set myself up with a PyPI account. PyPI, for those not in the python world, is the “Python Package Index” which lists all the uploaded packages and makes them easy to install onto systems. It’s sort of the python version of Perl’s CPAN, PHP’s PEAR or Ruby’s gems.

However, as I wrote about over on the Tropo blog, thanks to a developer suggesting we upload the Tropo WebAPI library to PyPI, I now finally have a PyPI account. My first (and currently only) submission is naturally:

http://pypi.python.org/pypi/tropo-webapi-python/0.1.0

Now that I’ve done that, I may take some of my other modules and upload them as well.

The cool part about this is that developers can now very easily install the Tropo WebAPI library and use it with their free Tropo account to start creating apps that use voice, SMS, IM, or Twitter for real-time communications (or near real-time, anyway). All they have to do is use one of these commands:

easy_install tropo-webapi-python

pip install tropo-webapi-python

depending upon whether they prefer easy_install or pip to install packages.

Cool stuff... and I'm glad I'm finally on the PyPI train! :-)

The Snowstorm of Dec 27, 2010 – Keene NH