Book Image

Node Cookbook - Fourth Edition

By : Bethany Griggs
4 (1)
Book Image

Node Cookbook - Fourth Edition

4 (1)
By: Bethany Griggs

Overview of this book

A key technology for building web applications and tooling, Node.js brings JavaScript to the server enabling full-stack development in a common language. This fourth edition of the Node Cookbook is updated with the latest Node.js features and the evolution of the Node.js framework ecosystems. This practical guide will help you to get started with creating, debugging, and deploying your Node.js applications and cover solutions to common problems, along with tips to avoid pitfalls. You'll become familiar with the Node.js development model by learning how to handle files and build simple web applications and then explore established and emerging Node.js web frameworks such as Express.js and Fastify. As you advance, you'll discover techniques for detecting problems in your applications, handling security concerns, and deploying your applications to the cloud. This recipe-based guide will help you to easily navigate through various core topics of server-side web application development with Node.js. By the end of this Node book, you'll be well-versed with core Node.js concepts and have gained the knowledge to start building performant and scalable Node.js applications.
Table of Contents (14 chapters)

Creating TCP server and client communication

Sockets allow machines and devices to communicate. Sockets are also used to coordinate I/O across networks. The term socket is used to refer to one endpoint of a two-way network communication link. Sockets enable us to build real-time web applications, such as instant messaging applications.

In this recipe, we will create a TCP server and a TCP client and allow them to communicate. TCP stands for Transmission Control Protocol. TCP provides a standard that allows devices to communicate over a network.

Getting ready

First, let's create a directory to work in:

$ mkdir communicating-with-sockets
$ cd communicating-with-sockets

We'll also need two separate files, one for the server and one for the client:

$ touch server.js
$ touch client.js

How to do it

First, we're going to create a TCP server using the net Node.js core module:

  1. We need to import the net module in server.js:
    const net = require("net");
  2. Now let's set up some variables to store the hostname and port that we want our server to run on:
    const HOSTNAME = "localhost";
    const PORT = 3000;
  3. Now, we can create the server, passing the HOSTNAME and PORT variables into the listen() function:
    net
      .createServer((socket) => {
        console.log("Client connected.");
      })
      .listen(PORT, HOSTNAME);
  4. Now we should add some socket event listeners. Add the following two event listeners below the console.log("Client connected."); line:
        socket.on("data", (name) => {
          socket.write(`Hello ${name}!`);
        });
  5. Now let's create the client. Again, we need to start by importing the net module in client.js:
    const net = require("net");
  6. Next, we can try and connect to the server we configured in server.js. We'll define the HOSTNAME and PORT variables again in this file:
    const HOSTNAME = "localhost";
    const PORT = 3000;
    const socket = net.connect(PORT, HOSTNAME);
  7. Now that we've connected to that socket, we can write to it:
    socket.write("World");
  8. We also need to add a function that will listen for data returned by the socket:
    socket.on("data", (data) => {
      console.log(data.toString());
    });
  9. Run your server with the following command:
    $ node server.js
  10. In a second shell, run client.js:
    $ node client.js
  11. In the shell where you're running server.js, you should see the output, Client connected:
    $ node server.js
    Client connected.
  12. And in the shell where you're running client.js, you should see that the socket has responded with Hello World!:
    $ node client.js
    Hello World!

We've successfully set up a TCP server and client and allowed them to communicate via sockets.

How it works

The first half of the recipe focused on creating a TCP server.

The recipe used the createServer() function from the core Node.js to http module and the net function to create the server. The function passed to createServer() accepts a function, and this function is executed each time a new connection is made to the server. The Node.js API documentation describes this function as a connectionListener function.

socket is passed as an argument to this connection listener function. It is possible to listen for events on the socket object. In the recipe, we listened for the data event and registered a function to execute each time data was received.

We then called the listen() function on createServer()—this function starts the server listening for connections. In the recipe, we passed the listen() function the hostname and port that we wanted the server to be accessible at. Note that it is also possible to listen on a Unix socket such as the following:

	const socket = net.connect("/tmp/my.socket");

Similarly, we also registered a data listener in client.js, which was listening for data written back from the server.

There are many other events that can be listened for on socket objects:

Figure 2.2 – Table listing socket events

Figure 2.2 – Table listing socket events

There's more

For some communications, UDP is more appropriate than TCP. Let's take a look at what UDP sockets are, what they're used for, and how to implement a UDP socket.

UDP stands for User Datagram Protocol and is an alternative to TCP. UDP is a connectionless protocol. Unlike TCP, the protocol does not establish a connection before sending data. UDP also doesn't guarantee delivery of packets—some can be lost. UDP is most often used in cases where speed is considered more important than reliability. UDP is typically used for video calling, gaming, or streaming—because in these cases, minimizing delay is important.

Node.js provides a core module named dgram that provides APIs to interact with UDP sockets. As with the other core modules, it can be imported with the following:

const dgram = require("dgram");

To create a socket, the dgram module exposes a createSocket() API:

const socket = dgram.createSocket("udp6");

We pass the udp6 function to instruct that we'd like the socket to interface over both IPv4 and IPv6.

To instruct the socket to start listening for connections, you use the bind function:

socket.bind(PORT);

Note that it is not necessary to provide a port. If none is provided (or you provide 0); the operating system will bind to a random free port.