Skip to main content

Introduction to Websockets

Tsim Sha Tsui, Hong Kong

TCP & UDP in Node.js

TCP Server

const net = require("net")

const port = 8080

const server = net.createServer(socket => {
    socket.write("Hello.")
    socket.on("data", data => {
        console.log(data.toString())
    })
})

server.listen(port)

You can run this file in Node.js:

node tcp.js

And connect to it using Telnet:

telnet 127.0.0.1 8080
Hello

Everything you type after that will be logged in your server console.

UDP Server

const dgram = require('dgram');
const socket = dgram.createSocket('udp4');

const port = 8081

socket.on('message', (msg, rinfo) => {
    console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});

socket.bind(port);
echo "hi" | nc -w1 -u 192.168.2.112 8081
server got: hi
 from 192.168.2.110:44757

HTTP in Node.js

var http = require('http')
var url = require('url')
var fs = require('fs')
var path = require('path')
var baseDirectory = __dirname   // or whatever base directory you want

var port = 80

http.createServer(function (request, response) {
    try {
        var requestUrl = url.parse(request.url)

        // need to use path.normalize so people can't access directories underneath baseDirectory
        var fsPath = baseDirectory+path.normalize(requestUrl.pathname)

        var fileStream = fs.createReadStream(fsPath)
        fileStream.pipe(response)
        fileStream.on('open', function() {
             response.writeHead(200)
        })
        fileStream.on('error',function(e) {
             response.writeHead(404)     // assume the file doesn't exist
             response.end()
        })
   } catch(e) {
        response.writeHead(500)
        response.end()     // end the response so browsers don't hang
        console.log(e.stack)
   }
}).listen(port)

console.log("listening on port "+port)
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content= "width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>A HTML Page</title>
    </head>
    <body>
        <h1>Just a Test</h1>
    </body>
</html>

Run node http.js and open the page inside your web browser or run the following from your Terminal:

curl htttp://localhost/index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content= "width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>A HTML Page</title>
    </head>
    <body>
        <h1>Just a Test</h1>
    </body>
</html>

Websockets in Node.js

Building a Websocket server in Node.js - starting by creating a basic http /tcp server:

const http = require("http")
const port = 8888

const server = http.createServer((req, res) => {
    console.log("Request received")
})

server.listen(port, () => console.log("Websocket Server listening on Port "+port))

Run the server with Node.js and try sending a GET request from your browser on http://localhost:8888/ - the line Request received should appear every time you send an request:

node index.js
Websocket Server listening on Port 8888
Request received

The server now is able to receive HTTP GET request. I now want to upgrade incoming requests to a websocket connection:

const http = require("http")
const WebSocket = require("websocket").server
let connection = null;
const port = 8888

const server = http.createServer((req, res) => {
    console.log("Request received")
})

const websocket = new WebSocket({
    "httpServer": server
})

websocket.on("request", request=> {
    connection = request.accept(null, request.origin);
    connection.on("open", () => console.log("Websocket connection established"))
    connection.on("message", message => {
        console.log(`message: ${message.utf8Data}`)
    })
    connection.on("close", () => console.log("Websocket connection closed"))
})

server.listen(port, () => console.log("Websocket Server listening on Port "+port))

Install the websocket module and re-run the server - sending an HTTP GET request should now initialize the websocket connection:

npm init -y
npm install websocket
node index.js

And I can use my browser console as the client application and send a message to my server:

ws = new WebSocket("ws://localhost:8888")
ws.onmessage = message => console.log(`${message.data}`)
ws.send("Hi")

To send a message from the Server to the Client I can add another to the server script:

const http = require("http");
const WebSocket = require("websocket").server;
let connection = null;
const port = 8888;

const server = http.createServer((req, res) => {
    console.log("Request received")
});

const websocket = new WebSocket({
    "httpServer": server
});

websocket.on("request", request=> {
    connection = request.accept(null, request.origin);
    connection.on("open", () => console.log("Websocket connection established"))
    connection.on("message", message => {
        console.log(`message: ${message.utf8Data}`)
    })
    connection.on("close", () => console.log("Websocket connection closed"))

    heartBeat();
});

server.listen(port, () => console.log("Websocket Server listening on Port "+port));

function heartBeat(){
    connection.send(`I am still here`);
    setTimeout(heartBeat, 30000);
};

Websockets in Node.js