Setting up the WebSocket Server in Node.js

Let’s continue the subject of writing the WebSocket server! In the previous post, we have set up a local environment on the machine.

In this post, we will start the project, install required packages, and finally write some JavaScript code!

Create a Folder πŸ“‚

The first thing that we need is a new folder in which we will set up the project.

You can create a new folder from the Terminal using mkdir command.

$ mkdir ./Server

Now we need to move to it using cd command.

$ cd ./Server

Create a Project πŸ’»

It’s time to start the project finally! To do it, we need to initialize a few things.

At the start, we need to initialize npm in the project. It will give us access to the packages which we will use later.

$ npm init
Result of the npm init command.

Great! With npm installed, now we can add some packages to our project!

The first one will be ws, which is simple and easy to use WebSocket library.

We can install it via npm using install parameter.

$ npm install ws
Installing ws package.

Next one will be uuidv4, which will generate unique ids for the connected clients.

Again we will use a similar command to the previous one.

$ npm install uuidv4
Installing uuidv4 package.

I think we have everything we need to start coding, finally!

Code time! πŸ€“

To start coding, we need to have a file! You can create it using the Terminal or the code editor of your choice.

Create a new file and name it server.js. After that, open it with the code editor.

We need a few things to import for our server to setup it. In our case, we will need http, url and ws packages.

By using them, we will be able to create some simple WebSocket server.

// Setting up server.
const http = require('http');
const server = http.createServer();
const port = 3000;

// Needed for parsing URLs.
const url = require('url');

// Setting WebSockets
const WebSocket = require('ws');
const wss = new WebSocket.Server({ noServer: true, clientTracking: true });

// Needed to generate player ids
const uuidv4 = require('uuid/v4');

Next is setting up the WebSocket server. It’s nothing crazy! WebSocket server is just reacting to the new connection or messages that the client is sending to the server.

...


// Websocket connection handler.
wss.on('connection', function connection(ws, request) {
  console.log(new Date() + ' | A new client is connected.');

  // Handle all messages from users.
  ws.on('message', function(msgStr) {
    console.log('Message: '+msgStr);

    // Send back the same message.
    ws.send(msgStr);
  });

  // What to do when client disconnect?
  ws.on('close', function(connection) {
    console.log(new Date() + ' | Closing connection for a client.');

    // One of the clients has disconnected.
  });
});

Over here, we also need to register our newly connected client and send him confirmation.

...


// Websocket connection handler.
wss.on('connection', function connection(ws, request) {
  console.log(new Date() + ' | A new client is connected.');

  // Assign player Id to connected client.
  var uuidPlayer = uuidv4();

  // Registering player with the session.
  let sessionMsg = {};
  sessionMsg.type = "register";
  sessionMsg.method = "register";

  // Gathering player connection key.
  let playerKey = request.headers['sec-websocket-key'];
  sessionMsg.sessionId = playerKey;
  sessionMsg.uuidPlayer = uuidPlayer;

  // Sending confirm message to the connected client.
  ws.send(JSON.stringify(sessionMsg));

  ...

});

This code won’t be called on its own. For that, we need the http server, which will pass the information to the WebSocket.

...

// HTTP Server ==> WebSocket upgrade handling:
server.on('upgrade', function upgrade(request, socket, head) {

    console.log(new Date() + ' | Upgrading http connection to wss: url = '+request.url);

    // Parsing url from the request.
    var parsedUrl = url.parse(request.url, true, true);
    const pathname = parsedUrl.pathname

    console.log(new Date() + ' | Pathname = '+pathname);

    // If path is valid connect to the websocket.
    if (pathname === '/') {
      wss.handleUpgrade(request, socket, head, function done(ws) {
        wss.emit('connection', ws, request);
      });
    } else {
      socket.destroy();
    }
});

Awesome! Now the only thing left is to start the server on the provided port! To do that, we have to start listening on the port.

...

// On establishing port listener.
server.listen(port, function() {
    console.log(new Date() + ' | Server is listening on port ' + port);

    // Server is running.
});

The result πŸ”¨

And that’s the skeleton of our WebSocket server. To test if it’s working we have to first run the server using node command in the Terminal.

$ node server.js
Server in action!

With the server running, we can test if it’s working by using websocat command in the other Terminal window.

$ websocat '-H Authorization: Basic somecrazypass' --text ws://localhost:3000/
Using websocat to connect to the WebSocket server.

How cool is it? 😎

In the next post, we will add another script to separate server logic from the game logic in it.

Do you have any questions? Let me know in the comment section below!

If you want to get notified of future content, sign up for the newsletter!

As always, the whole project is available at my public repository. πŸ”—

And I hope to see you next time! πŸ€“

avatar
  Subscribe  
Notify of