Have you ever wanted to create a real-time chat app or just curious about how the operation looks like under the hood?
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
Install dependencies: Express and Socket.io
Install Nodemon to automatically restart the server, save it as a Dev dependency by using the --save-dev flag
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
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
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'));
✍
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.
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);
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')
);
Let load socket.io to our front-end to establish the communication between both ends.
socket.io cdn
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).
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)
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');
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')
});
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)
});
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>
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');
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 = "";
});
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);
});
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>';
});
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
Then we attach an event listener to the message input using the keypress event and emit a message to the server
Next, we navigate into the server-side (index.js) and use the broadcast.emit method
And then we handle the on the front_end_Chat.js
Final test should look like the video in the link below.
I hope this guide is helpful😁.Thanks
Top comments (5)
Wao! Quite illustrative... Thanks
So is this gonna exchange text from my json-server ?, this is quiet impressive but I don't think messages are saved
@njokdan ...🙌 Thanks for reading.
i am writing this project on termux on my phone and i am in the wild mountain and for internet using Satellite 📡
@max Oralbay....nice... there's no boundary to doing the things we love, regardless of where we are