Thursday | 21 NOV 2024
[ previous ]
[ next ]

A Websocket Tutorial

Title:
Date: 2023-04-08
Tags:  

This will be a very simple tutorial to get a websocket server up and running in node!

The first step is to install the node package ws, we also want to install dotenv so we can get environment variables set up.

pnpm install ws dotenv

The next step is to create a .env file and add two values:

ENV="development"
PORT=8097

Now for the code, this will go index.js:

import dotenv from "dotenv";
dotenv.config();

import https from "https";
import fs from "fs";
import WebSocket, { WebSocketServer } from "ws";

const wsConfig = {};

if (process.env.ENV === "production") {
    let server = https.createServer({
        cert: fs.readFileSync("/home/test/cert/fullchain.pem"),
        key: fs.readFileSync("/home/test/cert/privkey.pem")
    }).listen(process.env.PORT)
    wsConfig.server = server;
} else {
    wsConfig.port = process.env.PORT;
}

const wss = new WebSocketServer(wsConfig);

console.log(`Running ${process.env.ENV} on port: ${process.env.PORT}`);

wss.on("connection", function connection(ws) {
    ws.on("error", console.error);
    ws.on("message", function message(data, isBinary) {
        console.log("received: %s", data);
        wss.clients.forEach(function each(client) {
            if (client !== ws && client.readyState === WebSocket.OPEN) {
                client.send(data, { binary: isBinary });
            }
        });
    });
});

The first part of the code deals with importing the various things we need. We need dotenv so we can load environment variables in. This way we can write the development code which won't be using any security and then the production code which will include security.

We will also using dotenv for the port number as the development port number and the production port number may be different.

The next import is https. This is a node builtin library to create a secure http server. We will need this when we go live with our websocket server. A websocket server will need to be secure if we are coming over https which presumably our site will be using.

The next import is the fs module which is also a builtin library. We need fs to read in the ssl certificate and key for the https server.

The last import is the one we've been waiting for, the websocket server itself. This is what we will be using as our main server.

The next chunk of code is the configuration. This is where the environment comes into play. In development we will have a very simple configuration. This is because, in development we can get away with not being secure, all we need to do is set the port we want to use.

In production, we will create a secure http server using the https library and we will specify the SSL certificate that our server should use. We also specify what port we want to listen on through the secure http server.

Once we have our configs, we can create an instance of the WebSocketServer using our config. This will create our server and it will now be running!

Now we can look at the code that the WebSocketServer, wss is going to be executing.

Websockets work on events and so we have 3 events that we have implemented. We have the connection event. This will get fired when a client connects to our websocket server. We have the error event that will get fired when there is an error. This will log the error.

The message event is the final event and the most important one. This is what will process messages from clients. In the above code, we take the message and send it back to all the clients that are currently connected. However we can do whatever we want here, for example we could check the message and client and route it to the correct user if it was a chat application.

In our case, we simply broadcast the message to everyone currently connected.

We can run our application by doing:

node index.js

Voila! We have our websocket server running now!

Let's now take a look at the front end code:

<script>
    cont socket = new WebSocket('ws://192.168.11.12:8097');
    socket.send("Hello, World!");
</script>

This is a very simple sender script. This can be added to an html page and this will send the server just Hello, World. If we open this page in the browser, we should see our server print "Hello, World!".

You should make a note here that ws at the front of the url is important. ws is used for insecure connections like our development server. When this goes live however, it will need to be changed to wss which signifies secure.

Now let's look at the front end code for received a message:

<script>
    cont socket = new WebSocket('ws://192.168.11.12:8097');
    socket.addEventListener("message", (event) => {
        console.log(event.data);
    });
</script>

If we open this page and then refresh our sender page, we should see a new message arrive both on our server and our receiver page!

We now have a working websocket server and can now start using this to build our own applications.