Building a Real-Time Chat Application with Websocket

Written by scofield | Published 2023/01/17
Tech Story Tags: websocket | chat-application | web-development | web-applications | javascript | webdev | websockets | frontend-development | web-monetization

TLDRWebSockets are a technology for creating real-time, bi-directional communication channels over a single TCP connection. They help build applications that require low-latency, high-frequency communication, such as chat applications. We will use Node.js as the server-side language and React as the client-side technology. The principles discussed in this tutorial can be applied to any language or technology that supports WebSockets.via the TL;DR App

WebSockets are a technology for creating real-time, bi-directional communication channels over a single TCP connection. They help build applications that require low-latency, high-frequency communication, such as chat applications, online gaming, and collaborative software.

In this tutorial, we will be building a real-time chat application using WebSockets and the Socket.IO library. We will use Node.js as the server-side language and React as the client-side technology. However, the principles discussed in this tutorial can be applied to any language or technology that supports WebSockets.

Prerequisites

Before we begin, you should have the following prerequisites:

  • Basic understanding of JavaScript
  • Basic understanding of Node.js and React
  • Basic understanding of web development concepts, such as HTTP and HTML
  • Node.js and npm installed on your machine
  • React developer tools installed in your browser (optional, but helpful for debugging)

Setting up the Server

First, let's create a new directory for our project and navigate to it in the terminal.

mkdir real-time-chat-app
cd real-time-chat-app

Next, let's create a new Node.js project by running the following command:

npm init -y

This will create a package.json file in our project directory.

Next, we need to install the Socket.IO library, which will handle the WebSocket communication for us.

Run the following command to install it:

npm install socket.io

Now let's create a new file called server.js in the root of our project directory. This will be the entry point for our server-side code.

In server.js, we first need to require the HTTP and socket.io modules:

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

Next, let's create an HTTP server and bind it to a port. We will use port 3000 for this example, but you can choose any available port on your machine.

const server = http.createServer((req, res) => {

  res.end('Server is running!');
});
const port = 3000;
server.listen(port, () => {
  console.log(`Server is listening on port ${port}`);
});

Now if we run the server by running node server.js in the terminal and navigate to http://localhost:3000 in the browser, we should see the message "Server is running!".

Next, we need to attach the Socket.IO server to our HTTP server. We do this by calling the listen method on the io object, and passing it to our HTTP server as an argument:

const ioServer = io.listen(server);

Now that we have set up the server, let's move on to setting up the client-side code.

Setting up the Client

First, let's create a new directory called client in the root of our project directory. This is where we will store the client-side code for our chat application.

Next, let's create a new React project in the client directory. Run the following command in the client directory:

npm start

Once you have created a new React project in the client directory, you should have a public and src directory inside the client directory.

Inside the src directory, create a new file called App.js. This will be the root component of our chat application.

First, let's import the required dependencies:

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

Next, let's create a function called useWebSocket that will handle the WebSocket communication for us.

This function will return an object with three properties:

  • messages: an array of messages that have been received from the server
  • sendMessage: a function that can be called to send a message to the server
  • error: an error object that will be set if there is an error in the WebSocket connection

Add the following code to App.js:

function useWebSocket() {   const [messages, setMessages] = useState([]);   const [error, setError] = useState(null);   useEffect(() => {     const socket = io('http://localhost:3000');     socket.on('connect', () => {       console.log('Connected to server!');     });     socket.on('disconnect', () => {       console.log('Disconnected from server');     });     socket.on('error', (error) => {       setError(error);     });     socket.on('message', (message) => {       setMessages((prevMessages) => [...prevMessages, message]);     });     return () => {       socket.disconnect();     };   }, []);   const sendMessage = (message) => {     if (socket.connected) {       socket.send(message);     }   };   return { messages, sendMessage, error }; }

This code uses the useEffect hook to set up the WebSocket connection when the component mounts. We are also using the useState hook to keep track of the messages and error state.

The useWebSocket function returns an object that contains the messages array, the sendMessage function, and the error object.

Now let's use the useWebSocket function in our App component. Add the following code to App.js:

function App() {
   const { messages, sendMessage, error } = useWebSocket();   if (error) {     return <div>Error: {error.message}</div>;   }   return (     <div>       <ul>         {messages.map((message) => (           <li>{message}</li>         ))}       </ul>       <form onSubmit={(event) => {         event.preventDefault();         const messageInput = event.target.elements.message;         sendMessage(messageInput.value);         messageInput.value = '';       }}>         <input name="message" />         <button type="submit">Send</button> function App() {   const { messages, sendMessage, error } = useWebSocket();   if (error) {     return <div>Error: {error.message}</div>;   }   return (     <div>       <ul>         {messages.map((message) => (           <li>{message}</li>         ))}       </ul>       <form onSubmit={(event) => {         event.preventDefault();         const messageInput = event.target.elements.message;         sendMessage(messageInput.value);         messageInput.value = '';       }}>         <input name="message" />         <button type="submit">Send</button>       </form>     </div>   ); }
 export default App;

Now let's move on to handling the messages on the server side.

Handling Messages on the Server

In the server.js file, let's add the following code to handle incoming messages:

ioServer.on('connection', (socket) => {   console.log('New client connected');   socket.on('message', (message) => {     console.log(`Received message from client: ${message}`);     ioServer.emit('message', message);   });   socket.on('disconnect', () => {     console.log('Client disconnected');   }); });

In this code, we use the connection event to handle new clients connecting to the server. We are also using the message event to handle incoming messages from the client and the disconnect event to handle clients that disconnect from the server.

When a message is received, we simply log it to the console and then emit it back to all connected clients using the emit method.

Now, if you start the server by running node server.js and navigate to http://localhost:3000 in the browser, you should be able to send messages and see them displayed in real-time.

Conclusion

This tutorial taught us how to create a real-time chat application using WebSockets and the Socket.IO library. We have set up a Node.js server and a React client and implemented the WebSocket communication using the useWebSocket hook on the client side and the connectionmessage, and disconnect events on the server side.

You can extend this application in many ways, such as adding user authentication, storing messages in a database, and implementing more advanced features like message editing and deletion. I hope this tutorial has provided a good foundation for you to build on.

Helpful Resources

Microsoft websockets
Basics of Websockets 


Also published here.


Written by scofield | Decentralized Dreamer, l love Web3, Cloud Computing and how to secure it all, anything else, please do not wake me up.
Published by HackerNoon on 2023/01/17