DEV Community

Cover image for Socket.io and NodeJS Chat Application Tutorial
alakkadshaw
alakkadshaw

Posted on • Originally published at deadsimplechat.com

Socket.io and NodeJS Chat Application Tutorial

In this article we will be building a socket.io and NodeJs Chat application

We will be building a pretty simple application that you can easily follow along and all the code will be available on github to easily download and run.

All the code is free and opensource

In this tutorial we will be building the app with basic HTML CSS along with Socket.io and NodeJS.

If you are interested in Angular Chat App with Socket.io and NodeJs

Prerequisites and Application Stack

We will be using the following technologies

  1. Basic Knowledge of HTML, CSS and JavaScript
  2. NodeJs
  3. Socket.io

💡
New to DeadSimpleChat? It's a turn key chat that you can easily add to your website or App —without any complicated code. For Virtual / Live events, SaaS App, Social Platform, Education, Gaming, Finance Sign Up for Free

Let us look at how the finished application with HTML and CSS front end will look like:

Image description

Step 1: Scaffolding a new project for chat with NodeJs

let us first start building the backend. Type the npm init command to initialize a new project.

let us name the project socketio-nodejs-chat-application

Image description

now let us install socket.io by typing the below command

npm install socket.io --save
Enter fullscreen mode Exit fullscreen mode

and install expressjs as well

npm install express --save
Enter fullscreen mode Exit fullscreen mode

Open the code in your favorite code editor I am using VSCode. The code should look like this

Image description

The package.json should look something like:

{
  "name": "socketio-nodejs-chat-application",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "DeadSimpleChat Team",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2",
    "socket.io": "^4.5.4"
  }
}
Enter fullscreen mode Exit fullscreen mode

Now create a new file called index.js and paste the below code in it.

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);


app.get('/', (req, res) => {
res.send('Hello World');
});

server.listen(3000, () => {
  console.log('listening on *:3000');
});
Enter fullscreen mode Exit fullscreen mode

What are we doing here

We have initialized the express and we are sending Hello world whenever a request comes to the server

type node index.js to start the server

Our express server is listening at port 3000 . So if we go to the localhost:3000 we can see the Hello World there like this:

Image description

Step 2 : Creating font-end for Chat with HTML and Socket.io

Let us now create a new file called index.html We will render this file using express.js

Paste the below code in the index.html file

<!DOCTYPE html>
<html>
  <head>
    <title>Socket.IO NodeJs Chat Application</title>
    <style>
      body { margin: 0; padding-bottom: 3rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }

      #form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; bottom: 0; left: 0; right: 0; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }
      #input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
      #input:focus { outline: none; }
      #form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; }

      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages > li { padding: 0.5rem 1rem; }
      #messages > li:nth-child(odd) { background: #efefef; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form id="form" action="">
      <input id="input" autocomplete="off" /><button>Send Message</button>
    </form>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

In this index.html file we are creating a chat layout with a form and input for writing text and a button to send the message

Plus list to display messages and highlighting that with CSS

Now edit the index.js file to send the index.html file instead of sending Hello World

We use the method res.sendfile to send a file.

app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
});
Enter fullscreen mode Exit fullscreen mode

The index.js should look like this

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);


app.get('/', (req, res) => {
    res.sendFile(__dirname + '/index.html')
    });    

server.listen(3000, () => {
  console.log('listening on *:3000');
});
Enter fullscreen mode Exit fullscreen mode

Now if you go to localhost:3000 you will the simple chat layout that we have created using html and CSS

Image description

Step 3: Adding Socket.io functionality

Now let us add the socket.io functionality to send messages. Paste the below code in index.js file

const { Server } = require("socket.io");
const io = new Server(server);


io.on('connection', (socket) => {
  console.log('a user connected');
});
Enter fullscreen mode Exit fullscreen mode

We initialize the instance of socket by passing the http server object to it.

Then we listen to the connection event for the incoming sockets and log it to the console

lets run it, restart the server by pressing ctrl +c and again typing node index.js

the server crashes, if we look into the console we see CORS error. let's fix this

In the index.js file type delete the code const io =newServer(server);

and type the code

const io = new Server(server, {
    cors: {
      origin: "*",
      methods: ["GET", "POST"]
    }
  });
Enter fullscreen mode Exit fullscreen mode

Now restart the server again. The index.js file should look like:

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server, {
    cors: {
      origin: "*",
      methods: ["GET", "POST"]
    }
  });

app.get('/', (req, res) => {
    res.sendFile(__dirname + '/index.html')
    });    

    io.on('connection', (socket) => {
        console.log('a user connected');
      });

server.listen(3000, () => {
  console.log('listening on *:3000');
});
Enter fullscreen mode Exit fullscreen mode

and open a new window and go to the localhost:3000 you will the following message in the console

listening on *:3000
a user connected
a user connected
Enter fullscreen mode Exit fullscreen mode

this is the server part, now let us add the socket.io in the HTML

Add the below script tags in the index.html file

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>
Enter fullscreen mode Exit fullscreen mode

The index.html file should look like this

<!DOCTYPE html>
<html>
  <head>
    <title>Socket.IO NodeJs Chat Application</title>
    <style>
      body { margin: 0; padding-bottom: 3rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }

      #form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; bottom: 0; left: 0; right: 0; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }
      #input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
      #input:focus { outline: none; }
      #form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; }

      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages > li { padding: 0.5rem 1rem; }
      #messages > li:nth-child(odd) { background: #efefef; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form id="form" action="">
      <input id="input" autocomplete="off" /><button>Send Message</button>
    </form>
  </body>
</html>

<script src="/socket.io/socket.io.js"></script>
<script>
    var socket = io();
  </script>
Enter fullscreen mode Exit fullscreen mode

Now you have connected the html with the NodeJs backend. The socket.io also fires a disconnect event whenever a disconnect event occurs

Add the below code in your index.js file to console.log when a user disconnects.

io.on('connection', (socket) => {
    console.log('a user connected');
    socket.on('disconnect', () => {
      console.log('user disconnected');
    });
  });
Enter fullscreen mode Exit fullscreen mode

now restart the server and reload the chat webpage you can see a user connected and user disconnected in the console.log

Next we need to emit events, socket.io supports any data that can be encoded in JSON (binary data is supported too).

So along with the events we can send the message that we want to broadcast to all the users connected to the chat

So, let us send the messages to the server as the user types them. For that type the below in the index.html file

<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 = '';
    }
  });
</script>
Enter fullscreen mode Exit fullscreen mode

and in our server we will receive the message and emit it or broadcast it to all the users connected to the chat

Step 4: Sending and receiving messages

In our chat example we will be sending the chat messages to every user that is connected to the chat, even the user that is sending the message

There is an io.broadcast.emit method if you want to send the message to everyone except the user who sent the message

Paste the below code in the index.js file

io.on('connection', (socket) => {
    socket.on('message', (msg) => {
      io.emit('message', msg);
    });
  });
Enter fullscreen mode Exit fullscreen mode

The total index.js code looks like

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server, {
    cors: {
      origin: "*",
      methods: ["GET", "POST"]
    }
  });

app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
});

io.on('connection', (socket) => {
  console.log('a user connected');
});

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

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

server.listen(3000, () => {
  console.log('listening on *:3000');
});
Enter fullscreen mode Exit fullscreen mode

On the index.html page we will capture the message sent from the server and show it on the chat webpage

In the index.html add the following code below the initialization code.

<script>
  var socket = io();

var messages = document.getElementById('messages');
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>
Enter fullscreen mode Exit fullscreen mode

The complete code for the chat looks like

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Socket.IO NodeJs Chat Application</title>
    <style>
      body { margin: 0; padding-bottom: 3rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }

      #form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; bottom: 0; left: 0; right: 0; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }
      #input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
      #input:focus { outline: none; }
      #form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; }

      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages > li { padding: 0.5rem 1rem; }
      #messages > li:nth-child(odd) { background: #efefef; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form id="form" action="">
      <input id="input" autocomplete="off" /><button>Send Message</button>
    </form>
  </body>
</html>

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();

var messages = document.getElementById('messages');
var form = document.getElementById('form');
var input = document.getElementById('input');

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

socket.on('chat message', function(msg) {
  var item = document.createElement('li');
  item.textContent = msg;
  messages.appendChild(item);
  window.scrollTo(0, document.body.scrollHeight);
});
</script>
Enter fullscreen mode Exit fullscreen mode

and index.js

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server, {
    cors: {
      origin: "*",
      methods: ["GET", "POST"]
    }
  });

app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
});

io.on('connection', (socket) => {
  console.log('a user connected');
});

io.on('connection', (socket) => {
    socket.on('chat message', (msg) => {
      io.emit('chat message', msg);
    });
  });

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

server.listen(3000, () => {
  console.log('listening on *:3000');
});
Enter fullscreen mode Exit fullscreen mode

and lastly package.json

{
  "name": "socketio-nodejs-chat-application",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "DeadSimpleChat Team",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2",
    "nodemon": "^2.0.20",
    "socket.io": "^4.5.4"
  }
}
Enter fullscreen mode Exit fullscreen mode

Our completed chat application looks like:

Image description

Using Pre-Built Chat

Making your own scale and reliable chat solution is a massive endeavour.

Instead you can choose DeadSimpleChat.com A pre-built chat for any use-case

  1. Group Chat
  2. Live Streaming Chat
  3. 1-1 Chat
  4. Chat API, SDK and Webhooks

DeadSimpleChat is a no code chat. you can easily add it to your website or app and customize it with the UI based customization.

But, there are APIs, a JavaScript SDK and Webhooks if you need precision customization and integration with your website and app

let us visit DeadSimpleChat and go through some of its features and functionality

Image description

you can create a free account by clicking on the Get Started for Free button

Once you have created an account you will land up on the Dashboard page

Here you can see Chat Analytics and Create a new Chat room by clicking on the create chat room button

you can create a free account by clicking on the Get Started for Free button

Once you have created an account you will land up on the Dashboard page

Here you can see Chat Analytics and Create a new Chat room by clicking on the create chat room button

Image description

When you click on the create chat room button. It asks you some basic questions like the name of the chat room, its description etc and then a chat room is created and you land on the General settings page of the chat room

Here you can enable disable chat room features according to your needs

Image description

There are a variety of settings here that you can customize the chat with

For example

  1. you can turn on/turn off the chat

  2. Ability to like/react to messages

  3. Q&A mode

  4. Sub Channels

  5. file and image sharing

  6. 1-1 Chat

  7. Password Protect chat

  8. Enable disable chat notifications

  9. Private room

  10. Eject All participants

  11. Export all messages and files

  12. Delete Chat rooms

Once you have customized the chat room setting you can customize the look of the chat room by going to the customize section

DeadSimpleChat has a UI based chat customization tool. You can customize the look of the chat exactly as you want to

You can even write Custom CSS to precision customize the look of the chat room

You can set the size of the chat room, copy customizations to other chat rooms and much more

All the chat rooms in DeadSimpleChat are completely independent of other chat rooms.

At the bottom you can see the embed code. Just paste the embed code on your website or app where you want to add the chat room and the chat is added on your website or app

Then you can create Channels/ sub rooms when are chat rooms inside of chat rooms

next to that is the translate tab. You can translate Dead Simple Chat UI into any language you want.

After that you can go to the embed page there you can see the embed info

You can also change the size of the chat room and add it as a chat bubble as well

Apart from this you can create moderators. Moderators can delete messages, ban users.

You can also ban bad words from the chat room. You can use our pre defined list or create custom bad words as well.

There are also API, Chat SDK and Webhooks as well.

You can refer to the developer documentation here as well

Conclusion

In this article we have made socket.io and NodeJs Chat app.

Top comments (1)

Collapse
 
arul_s8 profile image
Arul

A GitHub report sample code will help as well :)