Learn WebSockets By Building Simple Chat App
Tags: websockets, javascript, node
Published: 2019-11-03 14:00:21

The WebSocket API is a way to communicate between a client (user's browser) and a server. During the session, the data can flow bi-directional way in real-time, meaning the client can send the messages to the server, and the server can response back without the need to poll. Communication through the opened channel is long-lasting and low latency.

WebSockets perfect use cases:
- Chat apps
- Tracking apps
- Live audience interaction
- IoT device updates

## Building The App

To get a better understanding of what WebSockets can do, let's build a simple chat app where users can send and receive messages in real-time.

For the app, we will need:
1. Setup Node.js server with WebSocket library for Node.js `ws`
2. Create client-side (HTML and client.js) with WebSocket instance to listen for the message from the server

### Setting Up Server

Initialize the project from your terminal:

```jsx
npm i -Y && npm i ws && touch server.js
```
The command will set up the project, install the `ws` library, and create a `server.js` file.

Open `server.js` file from your editor and initialize the server:

```jsx
const WebSocket = require('ws');

// starts server instance on http://localhost:8080
const wss = new WebSocket.Server({ port: 8080 });
 
// waits for connection to be established from the client
// the callback argument ws is a unique for each client
wss.on('connection', (ws) => {

  // runs a callback on message event
  ws.on('message', (data) => {
  
    // sends the data to all connected clients
    wss.clients.forEach((client) => {
        if (client.readyState === WebSocket.OPEN) {
          client.send(data);
        }
    });
  });
});
```

### Setting Up Client

Create a simple HTML file with input to enter messages and send a button to post them. It does not matter where these files will be created;  it might be aswell in another directory as long as they are together.

```html
<!DOCTYPE html>
<html>

<body>
    <div id="chat"></div>
    <input id="name" type="text" placeholder="name" />
    <input id="message" type="text" placeholder="message" />
    <button id="send">Send</button>

    <script src="client.js"></script>
</body>

</html>
```

And for the `client.js` file, we will create a WebSocket API instance by specifying to listen to connection on `localhost:8080`.

```jsx
const connection = new WebSocket("ws://localhost:8080");
```

The `connection`, which is a WebSocket instance, has an extensive list of event properties. For this example, we won't use all of them, but the most important ones to notify the client and send messages to the server: 

- `WebSocket.onopen` - called when the connection is opened
- `WebSocket.onclose` - called when the connection is closed
- `WebSocket.onerror` - called when an error occurs
- `WebSocket.onmessage` - called when a message is received from the server

And the complete `client.js` file will look like this:

```jsx
const connection = new WebSocket("ws://localhost:8080");
const button = document.querySelector("#send");

connection.onopen = (event) => {
    console.log("WebSocket is open now.");
};

connection.onclose = (event) => {
    console.log("WebSocket is closed now.");
};

connection.onerror = (event) => {
    console.error("WebSocket error observed:", event);
};

connection.onmessage = (event) => {
  // append received message from the server to the DOM element 
  const chat = document.querySelector("#chat");
  chat.innerHTML += event.data;
};

button.addEventListener("click", () => {
  const name = document.querySelector("#name");
  const message = document.querySelector("#message");
  const data = `<p>${name.value}: ${message.value}</p>`;
  
  // Send composed message to the server
  connection.send(data);
  
  // clear input fields
  name.value = "";
  message.value = "";
});
```

## Run The App

In the terminal run command `node server.js` from within the project directory, open `index.html` file twice in separate browser tabs and try sending messages. Both client instances should receive messages through the server in real-time.
That completes the tutorial, and I hope you got a better understanding of how to use WebSockets for your next awesome project.