Using WebSockets with Socket.io and Node.js on Koyeb
Tags: webdev, node, programming, tutorial
Published: 2023-04-24 12:20:44

**With native support for WebSockets, Koyeb is a good place to run real-time applications globally in minutes. [Get started](https://app.koyeb.com) for free.**

## Introduction

Many types of applications depend on real-time communication: chat, gaming, live-streaming, and collaborative tools to name a few. To develop real-time applications using Node.js, you can use WebSockets or abstraction libraries like [Socket.io](https://socket.io/).

Socket.io provides a simple and easy-to-use API to create real-time applications.
It enables real-time, bidirectional, and event-based communication between a server and clients.
Using Socket.io as an abstraction layer, you get built-in capabilities such as rooms, namespaces, and automatic reconnection out of the box.

In this guide, we will create a simple chat application with Express and Socket.io and deploy it on Koyeb using git.
Koyeb provides built-in support for WebSocket connections, making it the ideal place to deploy your WebSocket applications.

## Requirements

To successfully follow and complete this guide, you need:

- A local development environment with Node.js installed
- A [GitHub account](https://github.com/) to version and deploy your application code on Koyeb
- A [Koyeb account](https://app.koyeb.com/) to deploy and run the application

## Steps

This guide will cover how to deploy an application using WebSockets with Socket.io and Node.js on Koyeb through the following steps:

1. [**Initialize the project to use Socket.io with Express**](#initialize-the-project-to-use-socketio-with-express)
2. [**Create the Socket.io server**](#create-the-server-using-express-and-socketio)
3. [**Create the Socket.io client**](#create-the-client-using-socketio)
4. [**Preview the app**](#preview-the-app)
5. [**Deploy on Koyeb**](#deploy-the-application-on-koyeb)

## Initialize the project to use Socket.io with Express

To get started, open your terminal and navigate to a location of your choice. Create the directory that will hold the application code:

```bash
mkdir socketio-on-koyeb
cd socketio-on-koyeb
```

Inside your app folder, create and initialize the package.json file. The package.json contains various metadata, gives npm information to identify the project, handles the project's dependencies, etc.

In your terminal run the following command:

```bash
$ npm init --yes

{
  "name": "socketio-on-koyeb",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
```

As our application uses the Express framework and Socket.io, we need to add them as dependencies of our project. In your terminal, run:

```bash
npm install express socket.io --save
```

Last, open the `package.json` file and add the following entry to the `scripts` section to be able to run the application running `npm run start`:

```diff-js
{
  "name": "socketio-on-koyeb",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
+    "start": "node server.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2",
    "socket.io": "^4.6.1"
  }
}
```

The project environment is now ready, we can now start writing our application.

## Create the server using Express and Socket.IO

Create and open a file named `server.js` and copy the content below:

```js
const express = require("express")
const app = express()

const port = process.env.PORT || 8000

app.get("/", function (req, res) {
  res.sendFile(__dirname + "/index.html")
})

app.listen(port, () => {
  console.log(`App listening on port ${port}`)
})
```

The code above creates a simple Express web server that serves an `index.html` file when a request is made to the root path `/`.

The next step is to initialize a new instance of Socket.io to be able to listen to incoming WebSocket connections.
We will also add the logic to handle client connection, disconnection, and emit an event of type `message` to all connected clients when a message is emitted by a client.

```diff-js
const express = require("express")
const app = express()
+const http = require("http").Server(app)
+const io = require("socket.io")(http)

const port = process.env.PORT || 8000

app.get("/", function (req, res) {
  res.sendFile(__dirname + "/index.html")
})

+io.on('connection', (socket) => {
+  console.log('Client connected')
+  socket.on('disconnect', () => {
+    console.log('Client disconnected')
+  });

+  socket.on('message', (msg) => {
+    io.emit('message', msg)
+  })
+})


+http.listen(port, () => {
  console.log(`App listening on port ${port}`)
});
```

The server is ready and properly integrated with Socket.io. We can now create a minimalistic `index.html` page that clients will use to connect to the server and send messages to each other.

## Create the client using Socket.IO

In the current app directory, create a file named `index.html` and copy the content below:

```html
<html>
  <body>
    <ul id="messages"></ul>
    <form id="form" action="">
      <input id="input" autocomplete="off" /><button>Send</button>
    </form>
    <script src="/socket.io/socket.io.js"></script>
    <script>
      var socket = io()

      var form = document.getElementById("form")
      var input = document.getElementById("input")

      form.addEventListener("submit", function (e) {
        e.preventDefault()
        if (input.value) {
          socket.emit("message", input.value)
          input.value = ""
        }
      })

      socket.on("message", function (msg) {
        var item = document.createElement("li")
        item.textContent = msg
        messages.appendChild(item)
        window.scrollTo(0, document.body.scrollHeight)
      })
    </script>
  </body>
</html>
```

## Preview the app

Launch the app running the following command:

```bash
npm run start
```

Open two different browser windows and navigate to http://localhost:8000 on each to see the chat application.
Each time you send a message, the server will emit a `message` event to all connected clients. The client will then append the message to the list of messages displayed on the page.

This means that by sending a message from your first browser window, the message will also appear in the second one and vice-versa.

We can now deploy the application on Koyeb.

## Deploy the application on Koyeb

We are going to deploy the application using git. If you want to learn how Koyeb automatically builds your application from git, read our [how we build from git](https://www.koyeb.com/docs/apps/build-from-git) documentation.

Initialize a new git repository on your local machine running:

```bash
git init
```

Add a new remote pointing to your GitHub repository:

```bash
git remote add origin git@github.com:<YOUR_GITHUB_USERNAME>/<YOUR_GITHUB_REPOSITORY>.git
```

Last, add the `server.js`, `package.json`, `package-lock.json` and `index.html` files to your repository and commit & push your changes:

```bash
git add server.js package.json package-lock.json index.html
git commit -m "Initial commit"
git push -u origin main
```

Next, you can deploy the app on Koyeb using the **control panel** or **Koyeb CLI**.

### Via the control panel

From the [Koyeb Console](https://app.koyeb.com/) click on the **Create App** button to import your project and configure your deployment.

1. Select **GitHub** as your deployment method
2. Pick your GitHub **repository** from the list, your **branch** is auto-detected
3. Name your App, for example `socketio-on-koyeb`

When you are done configuring your application, click the **Deploy** button to deploy your application.
You land on the deployment page where you can follow the progress of your application's deployment.
Once the build and deployment are completed, you can access your application by clicking the App URL ending with `koyeb.app` in the Koyeb control panel.

### Via the CLI

To deploy the app on Koyeb using the [Koyeb CLI](https://www.koyeb.com/docs/quickstart/koyeb-cli), you will need the Koyeb CLI installed. Once installed, run the following command in your terminal:

```bash
koyeb app init socketio-on-koyeb \
  --git github.com/<YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME> \
  --git-branch main \
  --ports 8080:http \
  --routes /:8080 \
  --env PORT=8080
```

_Make sure to replace <YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME> with your GitHub username and repository name._

**Access deployment logs**

To track the app deployment and visualize build logs, execute the following command:

```bash
koyeb service logs socketio-on-koyeb/socketio-on-koyeb -t build
```

**Access your app**

Once the deployment of your application has finished, you can retrieve the public domain to access your application by running the following command:

```bash
$ koyeb app get socketio-on-koyeb
ID      	NAME           	  STATUS 	DOMAINS                               CREATED AT
2b3c4170	socketio-on-koyeb	HEALTHY	["socketio-on-koyeb-myorg.koyeb.app"]	30 Mar 23 09:06 UTC
```

**Access runtime logs**

With your app running, you can track the runtime logs by running the following command:

```bash
koyeb service logs socketio-on-koyeb/socketio-on-koyeb -t runtime
```

## Conclusion

In this tutorial, we demonstrated how to deploy a real-time application using Socket.io and Express on Koyeb. We explained how to integrate Socket.io with Express, add the logic to handle client connection, disconnection, and emit events.

Thanks to Koyeb native support for WebSockets, you can easily deploy real-time applications globally effortlessly.

You can learn more about Socket.io and explore implementations in other languages by looking at the official [documentation](https://socket.io/docs/v4/).