Building a Real-Time Chat Application with WebSockets in React

Building a Real-Time Chat Application with WebSockets in React

Real-time communication is a vital feature in modern web applications. Whether for chat systems, collaborative tools, or live notifications, WebSockets enable seamless, two-way communication between the client and server.

In this article, we will build a real-time chat application using React on the frontend and WebSockets for real-time communication. By the end, you’ll understand the core concepts and have a functional chat app to showcase in your portfolio.


What is WebSocket?

WebSocket is a communication protocol that provides full-duplex, bi-directional communication between a client and a server over a single TCP connection. Unlike HTTP, where a connection is established and closed with each request, WebSockets maintain an open connection, allowing for real-time communication.


Setting Up the Environment

To build our chat application, we will use:

  • React for the frontend.

  • Node.js and Express.js for the backend.

  • Socket.IO for WebSocket implementation.


1. Backend Setup with Node.js and Socket.IO

Step 1: Initialize the Node.js Project

mkdir realtime-chat
cd realtime-chat
npm init -y

Step 2: Install Dependencies

Install the necessary packages:

npm install express socket.io

Step 3: Create the Server

Create a file named server.js and set up the server:

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

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

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

  // Handle incoming messages
  socket.on('sendMessage', (message) => {
    console.log('Message received:', message);

    // Broadcast the message to all clients
    io.emit('receiveMessage', message);
  });

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

const PORT = 5000;
server.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

Step 4: Run the Server

Start the server:

node server.js

2. Frontend Setup with React

Step 1: Create a React App

Create a React app using Create React App:

npx create-react-app realtime-chat-client
cd realtime-chat-client

Step 2: Install Socket.IO Client

Install the Socket.IO client library:

npm install socket.io-client

Step 3: Build the Chat Component

Create a Chat.js component to handle the real-time chat interface.

import React, { useState, useEffect } from 'react';
import { io } from 'socket.io-client';

const socket = io('http://localhost:5000');

const Chat = () => {
  const [messages, setMessages] = useState([]);
  const [inputMessage, setInputMessage] = useState('');

  useEffect(() => {
    // Listen for incoming messages
    socket.on('receiveMessage', (message) => {
      setMessages((prevMessages) => [...prevMessages, message]);
    });

    return () => {
      socket.off('receiveMessage');
    };
  }, []);

  const sendMessage = () => {
    if (inputMessage.trim() !== '') {
      socket.emit('sendMessage', inputMessage);
      setMessages((prevMessages) => [...prevMessages, inputMessage]);
      setInputMessage('');
    }
  };

  return (
    <div style={{ padding: '20px', maxWidth: '500px', margin: 'auto' }}>
      <h1>Real-Time Chat</h1>
      <div
        style={{
          border: '1px solid #ccc',
          padding: '10px',
          height: '300px',
          overflowY: 'scroll',
          marginBottom: '10px',
        }}
      >
        {messages.map((msg, index) => (
          <div key={index} style={{ margin: '5px 0' }}>
            {msg}
          </div>
        ))}
      </div>
      <input
        type="text"
        value={inputMessage}
        onChange={(e) => setInputMessage(e.target.value)}
        placeholder="Type a message"
        style={{ width: '80%', marginRight: '10px' }}
      />
      <button onClick={sendMessage} style={{ width: '18%' }}>
        Send
      </button>
    </div>
  );
};

export default Chat;

3. Run the Application

Start the React App

Run the React app:

npm start

Testing the Real-Time Chat

  1. Open the React app in two separate browser windows or devices.

  2. Type a message in one window and send it.

  3. Observe that the message appears in both windows instantly.


Key Features of the Chat App

  1. Real-Time Communication: Messages are instantly broadcast to all connected users.

  2. Persistent Connection: WebSockets ensure a constant connection between client and server.

  3. Scalable Backend: With Socket.IO, you can easily scale the server for multiple users.


Enhancements for Production

  • Authentication: Integrate user authentication to ensure secure communication.

  • Persistent Storage: Use a database like MongoDB to store chat history.

  • Styling: Add CSS for a polished and user-friendly UI.

  • Private Messaging: Implement rooms or private chat features using Socket.IO’s rooms functionality.


Conclusion

Building a real-time chat application with React and WebSockets is a great way to learn about real-time communication in web development. WebSockets provide a reliable and efficient way to implement live features in your apps.

Try extending this app by adding user authentication or integrating with a database for storing messages. The possibilities are endless!