WebSocket and node.js: why shud’ya care?
[tweetmeme source=”anismiles” only_single=false http://www.URL.com%5D
Traditional HTTP messages are heavy. Every message is sent with HTTP headers. Now, let’s say you have an application that has a real-time component, like chat or some twitter client or may be some traffic analysis stuff. And let’s say you have around 100,000 users connected to your app. To make your app real-time, you need to have a mechanism which will enable server to push data almost as soon as this data becomes available. You could do it in two ways: Write a script which will connect to server every few seconds to check if there is any data. With each attempt, full set of HTTP headers moves back and forth between client and server. That’s not very efficient. To save yourself with all these bandwidth hassles, you could use a popular trick known as long-polling, where your browser connects to server and server holds the connection open until there is some data available to be pushed.
Now, let’s assume that there are 100,000 users connected to your app and every 10 seconds some data is sent from server to clients. Following HTTP specs, every time some data is sent, full set of headers are shared between client and server. This is how they look,
Request header
GET / HTTP/1.1 User-Agent: ...some long user agent string... Host: animesh.org Accept: */*
Response header
HTTP/1.1 200 OK Date: Tue, 25 Jan 2011 17:32:19 GMT Server: Apache X-Powered-By: PHP/5.2.3 X-Pingback: http://animesh.org/endpoint/ Connection: close Transfer-Encoding: chunked Content-Type: text/html; charset=UTF-8
That’s approximately 350 bytes of data, per user every 10 seconds. That’s roughly 28,400,000 bits per second of network throughput for 100,000 users. Roughly 26.7 Mbps for only HTTP headers. Gosh!
WebSocket
WebSocket comes to resue. With web sockets, once a handshake is done between client and server, messages can be sent back and forth with a minimal overhead. That’s awesome. You do a handshake while establishing the connection, and of course handshaking needs all those HTTP headers, but after that, you only need to send the data… no headers. This greatly reduces the bandwidth usage and thus improves the performance. Let’s see how. This is how handshake headers look like,
Handshake Request header
GET /demo HTTP/1.1 Upgrade: WebSocket Connection: Upgrade Host: animesh.org Origin: http://animesh.org WebSocket-Protocol: sample
Handshake Response header
HTTP/1.1 101 Web Socket Protocol Handshake Upgrade: WebSocket Connection: Upgrade WebSocket-Origin: http://animesh.org WebSocket-Location: ws://animesh.org/ WebSocket-Protocol: sample
And now, the connection has been established and data can freely flow between server and client without having to exchange any HTTP headers until this connection is closed or broken and you do another handshake. Imagine how much bandwidth you are saving! Whoa!
Example
Let’s write a simple application to see and learn how this thing actually works. This application will have a server all the clients will connect to, and whenever one client writes something to the server, all clients will be notified.
Here is our server, written in Node.js. Let’s name it server.js
Note: Though you can very well write a web socket server using Node’s native APIs, however I chose to use Micheil Smith‘s node-websocket-server library. This library is simple, elegant and very easy to work with. It works by wrapping and extending Node’s server object.
var sys = require("sys"); // Library https://github.com/miksago/node-websocket-server var websocket = require('./lib/node-websocket-server/lib/ws/server'); // create web socket server var server = websocket.createServer(); // listen on port 8078 server.listen(8078); // when the server is ready server.addListener("listening", function() { sys.log("Listening for connections on localhost:8078"); }); // when a traditional HTTP request comes server.addListener("request", function(req, res) { res.writeHead(200, { "Content-Type" : "text/plain" }); res.write("This is an example WebSocket server."); res.end(); }); // when a client websocket connects server.addListener("connection", function(conn) { // when client writes something conn.addListener("message", function(message) { // iterate thorough all connected clients, and push this message server.manager.forEach(function(connected_client) { connected_client.write(JSON.stringify(conn.id + ": " + message)); }); }); });
Now, let’s write a simple client. We will create one HTML file and run it in Google Chrome. Let’s name is client.html
<!DOCTYPE html> <html> <head> <title>WebSocket - Simple Client</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js"></script> <script type="text/javascript"> $(function() { // bind form $('#payload-form').submit(function() { var payload = ($("input#payload").val()); socket.send(payload); // write to server return false; }); // open websocket var socket = new WebSocket('ws://localhost:8078'); socket.onopen = function() { // Web Socket is connected. send an initial random message. socket.send(Math.floor(Math.random()*11) + ' >> Hi, I am Mr. so-and-so!'); }; // append to '#log' whatever server pushes. socket.onmessage = function(ev){ msg = JSON.parse(ev.data); $('#log').append(JSON.stringify(msg) + '</br>'); } }) </script> </head> <body> <div id='payload-container'> <form id='payload-form'> <input type='text' name='payload' id='payload' value='Hello World' style="width:500px;"/> <input type='submit' value='push'/> </form> </div> <div id='log' style='display:block; border:1px solid lightgray;'></div> </body> </html>
Now, run your server, and open your client in multiple Chrome windows/tabs.
// run server $ node server.js
That’s it! Was is fun? I will write more on how to establish WebSocket connections from a Java client in the next blog.
I really like your transitions and quality. I have been writing for Ghost Writers for a while now, and they pay me very well to write blog posts like this, or articles. I clear $100-$200 on a poor morning.
Judging by your ability with the english language, you may enjoy doing the same.
It wouldnt hurt to check them out.Here are the details
Writers Wanted
February 1, 2011 at 3:41 pm
[…] a server and all clients connect to this server, and send and receive messages. We decided to use WebSocket for underlying connection between clients and server, and Phonegap to build clients. Our idea is to […]
WebSocket support in Android’s Phonegap apps « animesh kumar
February 3, 2011 at 11:53 am
Thank you for preparing such an article. Respect and affection, Marc suzkerberg
filmler indir
February 4, 2011 at 1:56 am
watch video base
watch video base
February 4, 2011 at 2:58 am
you have got an awesome blog here! would you wish to make some invite posts on my weblog?
Sherill Jumbo
February 16, 2011 at 7:16 am
Sherill, I would love that.
Animesh
May 10, 2011 at 9:30 am
[…] have already explored why node.js is quickly becoming the most popular kid in school. We chose the platform for Clickdummy specifically because we are a team of JavaScript experts […]
Building a Non-Trivial App in Node.js – Skookum Blog
March 24, 2011 at 2:08 am
I love the simplicity and clarify of this demo. I’ve been messing with Node.js and thinking about trying WebSockets lately, and your example here (esp. turning the form submit into a socket message) has given me new ideas. =)
Darren Torpey
May 10, 2011 at 6:06 am
Darren, glad that it could help you. 🙂
Animesh
May 10, 2011 at 9:30 am
Animesh, I am new to Node.JS and I am bit confused whether it is a Server like nginx, Apache etc. or a server side scripting language like PHP, Python etc or it can be used for both purposes. I have been doing a lot of work from a couple of days to get my hands dirty with node.js. In some posts you wrote a server code and I found a screen scraping code which is much like PHP curl library for the same purpose.
Rajiv Charan Tej K
July 9, 2011 at 8:53 pm
Rajiv,
I think it would be very wrong to compare Node with Nginx, Apache like servers or PHP, Pyhton like languages. Node is much different and much more than that.
Node is basically an eco-system built upon Google’s V8 engine using Javascript as its language. If you come form Java background, you can look at Node like a NIO implementation like Netty, Grizzly or Apache Mina. These frameworks allow you to write NIO based event-oriented network programs, like the way Node does. But, again Java suffers from decades of blocking/synchronized programming whereas Javascript it fully asynchronous.
Few weeks ago, IBM developer works published a very basic know-how on Node. Unfortunately even they could not catch a lof of things correctly. You might want to take a look at: https://anismiles.wordpress.com/2011/05/13/ibm-has-no-idea-what-node-js-is/
I hope, after reading these blogs, you would have a better understanding about what exactly node is. Ping me, if you need any more clarification.
-Animesh
Animesh
July 9, 2011 at 9:18 pm
Animesh – great blog! I would like some more details on how node.js compares to Grizzly. We have a node.js backend supporting a REST api. We are considering moving to jersey/grizzly mainly for the tools, but would like to make sure that we are not compromising performance in any way. If node.js is just being used to serve up REST responses, do you think its a good move to jersey/grizzly?
Ram
December 3, 2012 at 4:24 am
[…] https://anismiles.wordpress.com/2011/01/25/websocket-and-node-js-why-shud%E2%80%99ya-care/ you may try using Header Upgrade and […]
haproxy virtual host issues - Admins Goodies
August 10, 2011 at 1:18 pm
Nice introduction to web-sockets. The first para also makes a good case for SPDY, the web protocol that’s gaining acceptance.
Anand George (@anandgeor)
March 17, 2012 at 7:56 pm
can you please help me with simple code to consuming asp.net soap web services.
ashik
April 25, 2012 at 11:32 pm
Sorry Ashik. I am not into windows and related tech.
Animesh
April 26, 2012 at 9:57 am
no prob,thanks for your reply:)
ashik
April 26, 2012 at 10:49 am
Hello my family member! I want to say that this article is amazing, nice written and come with almost all significant infos. I’d like to peer more posts like this .
PHP developer, experienced web designer, freelancer web developer, web designer in india, web designer in bangalore, fast website building, SEO professional
September 25, 2012 at 12:55 am
Hi Animesh. I followed your client example written in this page:
https://anismiles.wordpress.com/2011/02/03/websocket-support-in-android%E2%80%99s-phonegap-apps/#comment-706
And your example written above in order to test my Android Websocket Client. But I got this error in logCat:
Uncaught Error: onerror not implemented. at file:///android_asset/www/websocket.js:88
Do you know please how to fix it?
Maher
November 18, 2012 at 9:55 pm
Probably, you should implement onError method in websocket.js file and tie that up with the backend java class. Let me know it helps, otherwise, I will try to take a look. It used to work earlier, but recently websocket drafts were revised and something must have broken for my phonegap-websocket implementation.
Jai Ho! Animesh Kumar http://www.animesh.org
On Sun, Nov 18, 2012 at 9:55 PM, animesh kumar
testrahatkosh
November 18, 2012 at 11:37 pm
Hello Animesh..wonder full job you done…i have a vc++ application in server…i want to send data into that server from android-phonegap applivcation..How can i achieve it?I am beginner in websocket implementation
jadeer
March 4, 2013 at 11:34 pm
Aw, this was a very good post. Taking a few minutes and actual effort to produce a top
notch article… but what can I say… I procrastinate a lot and
never seem to get nearly anything done.
Sun Servers
March 27, 2013 at 1:46 am
I hardly leave a response, however I looked at
a few of the comments on this page WebSocket and node.
js: why shud’ya care? | animesh kumar. I actually do have 2 questions for you if it’s allright. Is it simply me or do some of the responses look like they are left by brain dead individuals? 😛 And, if you are writing on additional social sites, I’d like to
keep up with everything new you have to post. Would you
make a list of every one of your public pages like your Facebook page, twitter
feed, or linkedin profile?
barney88fred.wordpress.com
April 17, 2013 at 12:22 am
Hi
i am using your code But it not calling open function , message function .I am using cordova 2.3.
Thanks
dsf
June 25, 2013 at 9:56 am
websocket-android-phonegap
// new socket
//var socket = new WebSocket(‘ws://192.168.12.171:8101/’);
//var socket = new WebSocket(‘ws://192.168.12.171:8101’);
document.addEventListener(“deviceready”, onDeviceReady, false);
function onDeviceReady() {
alert(“Ready”);
var socket = new WebSocket(‘ws://192.168.12.171:8101/’);
//socket.onmessage();
}
// push a message after the connection is established.
socket.onopen = function() {
alert(“open”)
socket.send(‘Hello World’)
};
// alerts message pushed from server
socket.onmessage = function(msg) {
alert(msg);
alert(JSON.stringify(msg));
};
// alert close event
socket.onclose = function() {
alert(‘closed————‘);
};
// now, close the connection after 10 seconds. (funny!)
setInterval(function() {
// socket.onopen();
socket.onmessage;
}, 100);
dsf
June 25, 2013 at 9:57 am
[…] WebSocket and node.js why shud’ya care « animesh kumar https://anismiles.wordpress.com/2011/01/25/websocket-and-node-js-why-shud%E2%80%99ya-care/ […]
Technology Radar | Gomes Blog
July 9, 2013 at 11:00 pm