Skip to main content
  1. Javascripts/

Realtime Chat with ExpressJS and Socket.IO: A Practical Guide

·1113 words·6 mins·
ExpressJS Socket.IO Realtime Chat Web Development NodeJS
Ifarra
Author
Ifarra
Disturbing the peace!!
Table of Contents

Realtime Chat with ExpressJS and Socket.IO: A Practical Guide
#

This tutorial will walk you through the process of building a basic realtime chat application using ExpressJS for the backend and Socket.IO to handle the realtime communication. This example provides a solid foundation for more complex chat applications.

Prerequisites
#

Before we begin, ensure you have the following installed on your machine:

  • Node.js and npm (Node Package Manager): You can download Node.js from the official website: https://nodejs.org/ NPM comes bundled with Node.js.
  • A code editor: VS Code, Sublime Text, or any editor of your choice.

Setting Up the Project
#

First, let’s create a new project directory and initialize a Node.js project.

  1. Create a project directory:

    mkdir express-chat
    cd express-chat
    
  2. Initialize a new Node.js project:

    npm init -y
    

    This command creates a package.json file with default settings.

  3. Install required packages:

    npm install express socket.io
    

    This installs ExpressJS for our web server and Socket.IO for handling realtime communication.

Building the Server (ExpressJS and Socket.IO)
#

Now, let’s create our server file (server.js) and configure ExpressJS and Socket.IO.

// server.js
const express = require('express');
const http = require('http');
const socketIO = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketIO(server);

const port = process.env.PORT || 3000;

// Serve static files (HTML, CSS, JS) from the 'public' directory
app.use(express.static('public'));

// Socket.IO logic
io.on('connection', (socket) => {
  console.log('A user connected:', socket.id);

  // Handle chat message event
  socket.on('chat message', (msg) => {
    console.log('Message received:', msg);

    // Broadcast the message to all connected clients
    io.emit('chat message', {
      user: socket.id.substring(0, 5), // Shorten socket ID for display
      message: msg,
    });
  });

  // Handle disconnection
  socket.on('disconnect', () => {
    console.log('User disconnected:', socket.id);
  });
});

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

Explanation:

  • We import the necessary modules: express, http, and socket.io.
  • We create an Express application (app) and an HTTP server (server) using http.createServer(app). Socket.IO needs the HTTP server.
  • We initialize Socket.IO by passing the HTTP server instance to it: socketIO(server).
  • We define the port the server will listen on, defaulting to 3000 if the environment variable PORT is not set.
  • app.use(express.static('public')) tells Express to serve static files (like our HTML, CSS, and JavaScript) from a directory named public. We’ll create this directory later.
  • io.on('connection', (socket) => { ... }) sets up a connection listener. This function is executed when a new client connects to the server. Each client gets its own socket object.
  • Inside the connection handler:
    • console.log('A user connected:', socket.id) logs the socket ID of the new client to the console.
    • socket.on('chat message', (msg) => { ... }) listens for a custom event named chat message from the client. When a message is received, the callback function is executed.
    • io.emit('chat message', { ... }) broadcasts the received message to all connected clients. The io.emit function sends a message to all connected sockets. We also include a shortened version of the user’s socket ID.
    • socket.on('disconnect', () => { ... }) listens for a disconnect event, which is triggered when a client disconnects.

Creating the Client-Side Interface (HTML, CSS, and JavaScript)
#

Next, create a directory named public in the root of your project:

mkdir public
cd public

Inside the public directory, create the following files: index.html, style.css, and script.js.

1. index.html:

<!DOCTYPE html>
<html>
<head>
  <title>Realtime Chat</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id="chat-container">
    <ul id="messages"></ul>
    <form id="message-form" action="">
      <input id="message-input" autocomplete="off" /><button>Send</button>
    </form>
  </div>

  <script src="/socket.io/socket.io.js"></script>
  <script src="script.js"></script>
</body>
</html>

Explanation:

  • We include a basic HTML structure with a title and links to our CSS and JavaScript files.
  • The chat-container div holds the chat interface elements.
  • messages is an unordered list that will display the chat messages.
  • message-form contains the input field (message-input) and a submit button.
  • <script src="/socket.io/socket.io.js"></script> includes the Socket.IO client library. Crucially, the server automatically serves this at /socket.io/socket.io.js.
  • <script src="script.js"></script> includes our custom JavaScript file.

2. style.css:

body {
  font-family: sans-serif;
  margin: 0;
  padding-bottom: 50px;
  background-color: #f0f0f0;
}

#chat-container {
  max-width: 600px;
  margin: 20px auto;
  background-color: #fff;
  border-radius: 5px;
  padding: 20px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

#messages {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

#messages li {
  padding: 5px 10px;
}

#messages li:nth-child(odd) {
  background: #eee;
}

#message-form {
  background: #000;
  padding: 3px;
  position: fixed;
  bottom: 0;
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
  left: 0;
  right: 0; /* Added to keep it centered */
}

#message-form input {
  border: 0;
  padding: 10px;
  width: 90%;
  margin-right: 0.5%;
}

#message-form button {
  background: rgb(130, 224, 255);
  border: none;
  padding: 10px;
  width: 9%;
}

This provides basic styling for our chat interface.

3. script.js:

const socket = io(); // Connect to the Socket.IO server

const messages = document.getElementById('messages');
const form = document.getElementById('message-form');
const input = document.getElementById('message-input');

form.addEventListener('submit', (e) => {
  e.preventDefault(); // Prevent form submission from reloading the page
  if (input.value) {
    socket.emit('chat message', input.value); // Send the message to the server
    input.value = ''; // Clear the input field
  }
});

socket.on('chat message', (data) => {
  const item = document.createElement('li');
  item.textContent = `${data.user}: ${data.message}`;
  messages.appendChild(item);
  window.scrollTo(0, document.body.scrollHeight); // Scroll to the bottom
});

Explanation:

  • const socket = io(); establishes a connection to the Socket.IO server running on the same host and port.
  • We get references to the HTML elements we need.
  • form.addEventListener('submit', (e) => { ... }) listens for the form submission event.
  • Inside the submit handler:
    • e.preventDefault(); prevents the default form submission behavior, which would reload the page.
    • socket.emit('chat message', input.value); sends a custom event named chat message to the server, along with the message text.
    • input.value = ''; clears the input field.
  • socket.on('chat message', (data) => { ... }) listens for the chat message event from the server.
  • Inside the message handler:
    • We create a new li element and set its text content to the received message.
    • We append the new li element to the messages list.
    • We scroll to the bottom of the page to keep the latest message visible.

Running the Application
#

  1. Save all files. Make sure server.js is in your project root and index.html, style.css, and script.js are in the public directory.

  2. Start the server:

    node server.js
    
  3. Open your browser and navigate to http://localhost:3000.

  4. Open multiple browser windows or tabs pointing to the same address. You should now be able to send messages from one window and see them appear in all the other windows in realtime.

Conclusion
#

Congratulations! You have successfully built a simple realtime chat application using ExpressJS and Socket.IO. This tutorial provides a fundamental understanding of how to set up a basic chat application. You can expand upon this foundation by adding features such as user authentication, private messaging, room support, and more. Remember to explore the Socket.IO documentation for advanced features and options.

Related

JavaScript DOM Manipulation: A Comprehensive Guide
·1871 words·9 mins
JavaScript DOM Web Development Frontend Manipulation
This article provides a detailed overview of JavaScript DOM manipulation, covering element selection, attribute modification, node creation and appending, and event handling techniques.
JavaScript Performance Optimization Techniques
·1666 words·8 mins
JavaScript Performance Optimization Web Development Front-End
This article explores practical JavaScript performance optimization strategies, focusing on efficient code writing, memory management, browser rendering, and modern tools for performance profiling.
Automating Your Daily Tasks with Python: Real-World Examples
·2036 words·10 mins
Python Automation Productivity Scripting Task Automation
This article explores practical applications of Python for automating common daily tasks, providing code examples and explanations to get you started.