BerandaComputers and TechnologyMaking a Basic Chat with Node.js WebSockets

Making a Basic Chat with Node.js WebSockets

Interaction between two users is one of the most awesome things about back-end development. Before I learned Node.js, I had always wanted to code a chat for me and my friends, but had no idea how to do this. Fortunately, we can program user interaction with WebSockets.

A WebSocket is a way for multiple computers to communicate with each other over multiple channels, with just one single connection. What this means is that we can now have networking between computers! WebSockets are widely used all across the web and can be programmed in almost all backend languages, including Node.js!

Coding WebSockets With Socket.io – Setting Up

To program our WebSocket (for our chat), we are going to be using a Node.js module called Socket.io. Socket.io allows for real-time communications between clients and is a server-side library for Node.js. Though there are other options such as ws, an NPM dependency that is also used for creating WebSockets, I have found through my experience that Socket.io is much easier, simpler, and quicker to set up, thus making it widely used among developers.

To start using Socket.io, create a new project, and navigate to your project in your computer’s terminal. Then, initialize your project with NPM.

npm init

After that, install Express and Socket.io as local dependencies.

npm i express socket.io --save

In addition, I am also going to install EJS for templating. If you don’t know what EJS is or how to use it, make sure to check out Templating With EJS and Node.js.

npm i ejs express-ejs-layouts --save

Now, in our index.js file, let’s create a simple express server.

var port = 3000;
var express = require('express')
var ejs = require('ejs')
var layouts = require('express-ejs-layouts')
var app = express();

app.set('view engine', 'ejs');
app.use(layouts);
app.use(express.static('public'));

var server = app.listen(port, () => {
  console.log(`Sever listening on port ${port}`);
});

Above is the code for a boilerplate Express server, as well as code for EJS. If you haven’t used Express before and want to learn about it, check out How to Add Express.js to a Node.js Web App.

Next, I’m going to set up my public, views, and controllers directories. I won’t need one for models because we won’t be connecting to a database. Finally, I’ll add my layout.ejs file to my views directory and set up a basic index page, called index.ejs, also in my views directory. Here’s my HTML code inside index.ejs:

Name:

Message:


First, I made a form where the user can enter their message and post it, and then I created a container to hold chat messages. What we need to do next is to create a Javascript file in the /public/js directory, and then link it to our index.ejs page. Once we creat our Javascript page, mine is called main.js, we can link it to our index.ejs page with:

Notice how I don’t say /public/js/main.js, I do this because the line: app.use(express.static('public') in our index.js page implies the /public for us, so I only have to say /js/main.js. After that, we need to create a controller file in our /controllers directory to handle routes. Mine is called homeController.js.

exports.renderIndex = (req, res) => {
  res.render('index');
}

Add the above snippet to your homeController.js file. This is the code to render our index.ejs page. Finally, the last thing we need to do for our chat’s setup is to add a GET route to our index.js page.

//require homeController.js for our renderIndex() function
var homeController = require('/controllers/homeController.js');

//add the route for our chat
app.get('/', homeController.renderIndex);

Whew! That was a lot to setup. Now, to run our application, navigate to your project in your computer’s terminal and run node index.js.

If you got lost along the way or want to verify your code, the setup code is here under the setup branch. https://github.com/the-javascript-ninja/basic-chat-with-websockets

Coding the WebSocket

Now it’s time for the hard part: coding the WebSocket. If you ran the code we set up earlier, you would notice that the form doesn’t actually work yet. This is because we need to code the WebSocket so devices can interact.

To start programming our WebSocket, I’m going to create a new controller called socketController.js. This will help to manage our WebSocket without cluttering up our index.js file. To do this, add the following bit to your index.js file:

var io = require('socket.io')(server);
var socketController = require('./controllers/socketController.js')(io);

What this snippet does is it first requires socket.io, and then it passes socket.io to our socketController so socketController can handle the requests.

Next, add this portion of code to socketController.js.

module.exports = (io) => {
  io.on('connection', (client) => {
    console.log('User Connected');

    client.on('disconnect', () => {
      console.log('User Disconnected');
    });
  });
}

This code does the following:

1. Creates a function to handle socket requests. module.exports is a way of telling Node.js to export this function so that the index.js file can use it.

2. When a client connects, log a message to the console. The function io.on('connection', client => {}) means that when the socket receives a connection, it creates an object for the connected user.

3. When the client disconnects, log a message to the console.

Now that we’ve programmed the server side of our WebSocket, we have to connect to it from the client side. The first thing we need to do is to add this script tag to the bottom of our index.ejs file.

This script is needed for socket.io to work. Finally, add the following small line of code to get the client connected to the WebSocket.

var socket = io();

Awesome! Now, when you run your program, you will connect and disconnect to the WebSocket each time you log on and off.

Adding Chat Messages

Now we want to add chat messages so that when a user posts a message with our form, all the users connected to the WebSocket receive it. First, we will need to edit our function in socketController.js. Add the code below.

client.on('message', (mes) => {
  io.emit('message', mes);
});

There are two functions we are using in the code above: .on() and .emit(). .emit() is simple; it sends a message to the WebSocket. .on() detects when somebody has used .emit(). The code above is saying, when somebody sends a message to the WebSocket, the WebSocket sends the message back to everybody on the WebSocket. The code in socketController.js should look like this:

module.exports = (io) => {
  io.on('connection', (client) => {
    console.log('User Connected');

    client.on('message', (mes) => {
      io.emit('message', mes);
    });

    client.on('disconnect', () => {
      console.log('User Disconnected');
    });
  });
};

Now we need to make some edits on the client side. Navigate to main.js and add the following:

socket.on('message', (mes) => {
  var elem = document.createElement('p');
  var messageContainer = document.getElementById('messageContainer');
  messageContainer.insertBefore(elem, messageContainer.childNodes[0]);
  elem.textContent = mes;
});

function sendMessage() {
  var name = document.getElementById('name');
  var message = document.getElementById('message');
  socket.emit('message', `${name.value}: ${message.value}`);
  name.value = '';
  message.value = '';
}

The first function listens for when a message is received. Then, it creates a new paragraph element, puts it at the top of the message list, and sets its text content to display the received message. The second function is the one that will send messages. When it is called, the function will use socket.emit() to send a message to the WebSocket containing the sender’s name and what they said. Then, it resets the form fields.

There’s only one more thing left to do: call the sendMessage() function when the Post button is clicked. To do this, we just need to add the attribute onclick='sendMessage()', so the button’s code should look like this:

Our chat is done! you can run the whole thing by navigating to the project in your computer’s terminal and running node index.js.

Final Touches

While the chat function of our app is complete, it is still far from finished. I am not going to walk you through it, but I would highly recommend adding in some CSS.

In addition, if you got lost or confused at any point in this tutorial, you can view the final code Here on GitHub. The final code is under the master branch.

Read More

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments