DEV Community

Cover image for Chat App using Socket.io
Abayomi Ogunnusi
Abayomi Ogunnusi

Posted on • Updated on

Chat App using Socket.io

Have you ever wanted to create a real-time chat app or just curious about how the operation looks like under the hood?

phone

Today we will be discussing how we can communicate with the client, browser, and server using NodeJS, ExpressJs, and Socket.io

First, let's define what a web socket is.
Web Socket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection.
This communication is bi-directional and allows real-time data flow (transfer) because web sockets are always opened.

Prerequisite

✔ NodeJS fundamentals
✔ JavaScript Fundamentals
✔ Fair knowledge of NPM

Getting Started

To-do

  • Initiate our project
  • Install Packages
  • Set Up Express app and listen to the server
  • Create a static middleware
  • Use socket.io on the server-side (index.js) and in the front end (index.html)
  • Querying Document Object Model (DOM)
  • Broadcasting Messages

Follow instructions to start the project

Initiate your project using npm init and pass the '-y' flag to default all questions. This creates your package.json file that tracks all the dependencies and list information about the project

carbon (2)

Install dependencies: Express and Socket.io

carbon (4)

Install Nodemon to automatically restart the server, save it as a Dev dependency by using the --save-dev flag

carbon (5)

Create an entry point, in this case, I will use index.js. Feel free to change your main entry file on the package.json
So let's set up our express application and create an instance of an express app

carbon (1)

Let's test ⛏ out the application by running Nodemon index on the terminal.
If you set up your app correctly, You will get the result below

[nodemon] starting `node index.js`
App is listening to server on port 3000
Enter fullscreen mode Exit fullscreen mode

When you run localhost:3000 on your browser, the response is

cannot GET /

. To be able to serve static files such as HTML, images, CSS to the browser, create a folder called "public", an index.html, and write the middleware in your index.js file.

// Static files middleware
app.use(express.static('public'));
Enter fullscreen mode Exit fullscreen mode


Note: Middleware is functions written between your request and response. Express automatically looks inside the public folder (static file) and serves the index.html.

For demonstration, let's flesh out a boilerplate inside the index.html file.

carbon (6)
So when you refresh the initial localhost:3000 it will serve Home Page on the browser screen

Next up is to use socket.io in our index.js by first requiring the socket module

const socket = require('socket.io');

And then set up socket.io and link to the server the express app is listening to

const io = socket(server);
Enter fullscreen mode Exit fullscreen mode

At this point, the server is open and awaiting an event to be fired.

To make the WebSocket listen to an event when a particular client connects to the server, we write the function below.

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

Let load socket.io to our front-end to establish the communication between both ends.
socket.io cdn

socket i

Copy the link above from the socket.io CDN and paste it inside the index.html file inside the public folder as a script file. (Highlighted in yellow).

carbon (7)

The next thing is to create a JavaScript file inside the public folder where we run the socket.io logic on the front-end. I will name it front_end_Chat.js and make reference to it inside the index.html. (highlighted in red)

carbon (9).

Explanation ✍

When we load the index.html served to us in the browser, the browser loads in the socket.io CDN (highlighted in yellow above) and then runs the front_end_Chat.js file.

Next is to establish the connection with the backend server inside the front_end_Chat.js file to create a web socket between both ends.

// Make connection front-end setup
const socket = io.connect('http://localhost:3000');
Enter fullscreen mode Exit fullscreen mode

Here, when we load up the index.html file in the browser, we run the socket.io file, get to the front_end_Chat.js, make the connection on the just written function above, we listen to the connection on the backend inside the index.js file (see reference below) and log the message ' Socket connected successfully' on our terminal when we refresh the page.

// Backend connection
io.on('connection', (socket) => {
console.log('Socket connected successfully')
});
Enter fullscreen mode Exit fullscreen mode

We can log different socket unique IDs to the console every time we refresh the server or a different computer connects to the same IP address. In this case http://localhost:3000

// Backend connection
io.on('connection', (socket) => {
console.log('Socket connected successfully', socket.id)
});
Enter fullscreen mode Exit fullscreen mode

At this point, we have set up socket.io both on the front end and the backend. Now let's look at how we can emit a message to different clients (browser) by transferring data between both ends through information we set on our front-end.

Here, we create inputs and a button in our index.html files to store and send user information and message.

    <div id="tiny-chat">
        <div id="tiny-window">
            <div id="output"></div>
            <div id="feedback"></div>
        </div>
        <input id="handle" type="text" placeholder="Handle" />
        <input id="message" type="text" placeholder="Message" />
        <button id="send">Send</button>
    </div>
Enter fullscreen mode Exit fullscreen mode

Thereafter, we flesh out the JavaScript on the front-end i.e front_end_Chat.js which interacts with the inputs and button above and emits a message through the JavaScript File from the client down to the server.

I used id to style the chatroom. Find the codebase on my GitHub.
Github Link

The next thing to do is to Query the DOM inside the front_end_Chat.js

// Query DOM
const message = document.getElementById('message'),
    handle = document.getElementById('handle'),
    btn = document.getElementById('send'),
    output = document.getElementById('output');
Enter fullscreen mode Exit fullscreen mode

The next thing is to emit a message when a user clicks on the send button using Vanilla JavaScript inside the same file.

// Emit events
btn.addEventListener('click', function() {
    socket.emit('chat', {
        message: message.value,
        handle: handle.value
    });
    message.value = "";
});
Enter fullscreen mode Exit fullscreen mode

Explanation ✍

When we click the send button (btn), we listen for a click event, then fires a call back function, emit a message using the socket.emit function. The emit function takes two parameters (the name of the message which we call 'chat') and message (data sent to the server).

Next up, we need to handle the message sent from the front end on the server (index.js) by listening to the message.

const io = socket(server);
io.on('connection', (socket) => {

    console.log('made socket connection', socket.id);

    // Handle chat event
    socket.on('chat', function(data) {
        console.log(data);
        io.sockets.emit('chat', data);
    });
Enter fullscreen mode Exit fullscreen mode

On the front-end, We need a way to handle and output the data emitted on the socket.on function to the DOM. On the front_end_Chat.js we write the function below to listen for events.

// Listen for events
socket.on('chat', function(data) {
    feedback.innerHTML = '';
    output.innerHTML += '<p><strong>' + data.handle + ': </strong>' + data.message + '</p>';
});
Enter fullscreen mode Exit fullscreen mode

Lastly, we will need to broadcast the message emitted to the server to every web socket and client connected to it in real-time except the client sending the message.

To achieve this we need another input method to display the feedback sent from the server. Here, we use a div element on the index.html and make a reference to it in the front_end_Chat.js
carbon (10)

carbon (11)

Then we attach an event listener to the message input using the keypress event and emit a message to the server

carbon (12)

Next, we navigate into the server-side (index.js) and use the broadcast.emit method

carbon (13)

And then we handle the on the front_end_Chat.js
carbon (15)

Final test should look like the video in the link below.

Tiny Video

I hope this guide is helpful😁.Thanks
over

Resources

Web Socket Definition
Video Reference

Top comments (5)

Collapse
 
njokudanielo profile image
NJOKU DANIEL

Wao! Quite illustrative... Thanks

Collapse
 
paul_amoah_02a8dab49e1d69 profile image
Paul Amoah

So is this gonna exchange text from my json-server ?, this is quiet impressive but I don't think messages are saved

Collapse
 
drsimplegraffiti profile image
Abayomi Ogunnusi

@njokdan ...🙌 Thanks for reading.

Collapse
 
maxoralbay profile image
Max Oralbay

i am writing this project on termux on my phone and i am in the wild mountain and for internet using Satellite 📡

Collapse
 
drsimplegraffiti profile image
Abayomi Ogunnusi

@max Oralbay....nice... there's no boundary to doing the things we love, regardless of where we are