// Use the http module: http://nodejs.org/api/http.html var http = require('http'); // http://nodejs.org/api/http.html#http_event_request function onRequest(req, res) { //req is an IncominMessage: http://nodejs.org/api/http.html#http_http_incomingmessage //res is a ServerResponse: http://nodejs.org/api/http.html#http_class_http_serverresponse res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); // Send a log message to the console console.log("Got a request " + req.url); } // Call the createServer method, passing in an anonymous callback function that will be called when a request is made var httpServer = http.createServer(onRequest); // Tell that server to listen on port 8080 httpServer.listen(8080); console.log('Server listening on port 8080');
To run, save this as "httpserver.js", upload it to your server and run it with:
node httpserver.js
A basic webserver is great but it would be nice to serve other files such as images, javascript files, css, and the like from the filesystem. Here is an example:
var http = require('http'); var fs = require('fs'); // Using the filesystem module var httpServer = http.createServer(requestHandler); var url = require('url'); httpServer.listen(8080); console.log('Server listening on port 8080'); function requestHandler(req, res) { var parsedUrl = url.parse(req.url); console.log("The Request is: " + parsedUrl.pathname); // Read in the file they requested fs.readFile(__dirname + parsedUrl.pathname, // Callback function, called when reading is complete function (err, data) { // if there is an error if (err) { res.writeHead(500); return res.end('Error loading ' + parsedUrl.pathname); } // Otherwise, send the data, the contents of the file res.writeHead(200); res.end(data); } ); }
A great write-up/explanation/tutorial for getting started with Node: http://www.nodebeginner.org/
Unfortunately, in the above example, the server will shutdown and stop running once you log out or stop it with cntrl-c. Forever is a node module that allows us to run a node server in the background.
Install the module:
npm -g install forver
Then run the server with it:
forever start httpserver.js
List running servers (running using forever)
forever listwhich should output a list of running forever scripts
info: Forever processes running data: uid command script forever pid logfile uptime data: [0] GpWl /usr/local/bin/node server.js 16677 16679 /root/.forever/GpWl.log 0:0:0:14.683This shows one process running with the ID of GpWl (which is important if you want to shut it down). It's log file is here: /root/.forever/GpWl.log which is where any output that it generates will be written.
Stop it
forever stop ID(see above for the ID)
More information: http://blog.nodejitsu.com/keep-a-nodejs-server-up-with-forever
Socket.io is a node module that makes working with WebSockets easier. It also transparently supports older methods such as AJAX in the event that the browser doesn't support Web Sockets.
Before we do any programming, we should install the module in the directory we are going to use
npm install socket.io
Here is a basic example that we can go through:
// HTTP Portion var http = require('http'); var fs = require('fs'); // Using the filesystem module var httpServer = http.createServer(requestHandler); var url = require('url'); httpServer.listen(8080); function requestHandler(req, res) { var parsedUrl = url.parse(req.url); console.log("The Request is: " + parsedUrl.pathname); // Read in the file they requested fs.readFile(__dirname + parsedUrl.pathname, // Callback function for reading function (err, data) { // if there is an error if (err) { res.writeHead(500); return res.end('Error loading ' + parsedUrl.pathname); } // Otherwise, send the data, the contents of the file res.writeHead(200); res.end(data); } ); } // WebSocket Portion // WebSockets work with the HTTP server var io = require('socket.io').listen(httpServer); // Register a callback function to run when we have an individual connection // This is run for each individual user that connects io.sockets.on('connection', // We are given a websocket object in our function function (socket) { console.log("We have a new client: " + socket.id); // When this user "send" from clientside javascript, we get a "message" // client side: socket.send("the message"); or socket.emit('message', "the message"); socket.on('message', // Run this function when a message is sent function (data) { console.log("message: " + data); // Call "broadcast" to send it to all clients (except sender), this is equal to // socket.broadcast.emit('message', data); socket.broadcast.send(data); // To all clients, on io.sockets instead // io.sockets.emit('message', "this goes to everyone"); } ); // When this user emits, client side: socket.emit('otherevent',some data); socket.on('otherevent', function(data) { // Data comes in as whatever was sent, including objects console.log("Received: 'otherevent' " + data); }); socket.on('disconnect', function() { console.log("Client has disconnected"); }); } );
Save this file as whatever.js and upload it to a new directory on your server.
Here is the corresponding index.html file that should be uploaded to the same directory. (Don't forget to replace the SERVER_NAME with your server's name or address.):
<html> <head> <script src="/socket.io/socket.io.js"></script> <script> var socket = io.connect('http://SERVER_NAME:8080/'); socket.on('connect', function() { console.log("Connected"); }); // Receive a message socket.on('message', function(data) { console.log("Got: " + data); document.getElementById('messages').innerHTML += data; }); // Receive from any event socket.on('news', function (data) { console.log(data); }); var sendmessage = function() { var message = document.getElementById('message').value; console.log("Sending: " + message); // Send a messaage socket.send(message); }; var sendother = function() { var othermessage = document.getElementById('message').value; console.log("sending: " + othermessage); // Send any kind of data with a custom event //socket.emit('otherevent',{ othermessage: othermessage }); socket.emit('otherevent', othermessage); }; </script> </head> <body> <div id="messages"> No Messages Yet </div> <div> <input type="text" id="message" name="message"> <input type="button" value="message" onclick="sendmessage();"> <input type="button" value="other" onclick="sendother();"> </div> </body> </html>
More documentation and examples: http://socket.io/ and https://github.com/Automattic/socket.io
How about using this with the JavaScript Canvas.
Starting with the HTML. (Don't forget to replace the SERVER_NAME with your server's name or address.) Let's call it canvas_socket.html:
<html> <head> <script type="text/javascript" src="/socket.io/socket.io.js"></script> <script type="text/javascript"> var socket = io.connect('http://SERVER_NAME:8080/'); socket.on('connect', function() { console.log("Connected"); }); // Receive from any event socket.on('othermouse', function (data) { console.log(data.x + " " + data.y); odraw(data.x,data.y); }); var sendmouse = function(xval, yval) { console.log("sendmouse: " + xval + " " + yval); socket.emit('othermouse',{ x: xval, y: yval }); }; /////////////// var canvas; var context; var initcanvas = function() { canvas = document.getElementById('mycanvas'); context = canvas.getContext('2d'); context.fillStyle="#FF0000"; context.fillRect(0,0,canvas.width,canvas.height); canvas.addEventListener('mousemove', function(evt) { console.log("mousemove " + evt.clientX + " " + evt.clientY); //evt.clientX is x but in the entire window, not the canvas //evt.clientY is y // Get the canvas bounding rect var canvasRect = canvas.getBoundingClientRect(); // Now calculate the mouse position values y = evt.clientY - canvasRect.top; // minus the starting point of the canvas rect x = evt.clientX - canvasRect.left; // minus the starting point of the canvas rect on the x axis console.log("mousemove x:" + x + " y:" + y); sendmouse(x,y); draw(x,y); }, false); }; var px = 0; var py = 0; var draw = function(xval,yval) { console.log("draw " + xval + " " + yval); context.beginPath(); // This is silly but it's what we have to do to get a random hex string context.strokeStyle='#000000'; context.moveTo(px,py); context.lineTo(xval,yval); context.stroke(); px = xval; py = yval; }; var opx = 0; var opy = 0; var odraw = function(xval,yval) { console.log("draw " + xval + " " + yval); context.beginPath(); context.strokeStyle='#000000'; context.moveTo(opx,opy); context.lineTo(xval,yval); context.stroke(); opx = xval; opy = yval; }; </script> </head> <body onload="initcanvas();"> <canvas width="600" height="600" id="mycanvas" /> </body> </html>
Now the javascript server portion:
// HTTP Portion var http = require('http'); var fs = require('fs'); // Using the filesystem module var httpServer = http.createServer(requestHandler); var url = require('url'); httpServer.listen(8080); function requestHandler(req, res) { var parsedUrl = url.parse(req.url); console.log("The Request is: " + parsedUrl.pathname); fs.readFile(__dirname + parsedUrl.pathname, // Callback function for reading function (err, data) { // if there is an error if (err) { res.writeHead(500); return res.end('Error loading ' + parsedUrl.pathname); } // Otherwise, send the data, the contents of the file res.writeHead(200); res.end(data); } ); } // WebSocket Portion // WebSockets work with the HTTP server var io = require('socket.io').listen(httpServer); // Register a callback function to run when we have an individual connection // This is run for each individual user that connects io.sockets.on('connection', // We are given a websocket object in our function function (socket) { console.log("We have a new client: " + socket.id); // When this user emits, client side: socket.emit('otherevent',some data); socket.on('othermouse', function(data) { // Data comes in as whatever was sent, including objects console.log("Received: 'othermouse' " + data.x + " " + data.y); // Send it to all of the clients socket.broadcast.emit('othermouse', data); }); socket.on('disconnect', function() { console.log("Client has disconnected " + socket.id); }); } );