Real-Time Data Transfer Using Socket.io

Muhammad Umar Al Fajar
4 min readDec 8, 2023

--

Hello, on this occasion I want to share my learning journey of transfer data in real-time using Socket.io by building a Real-time Chat app. First, I want to explain a few things like why we need a real-time application, what is WebSocket, and why using Socket.io. In this article, the main focus is how to implement Socket.io and not to build the Chat App. But don’t worry, I’ll provide the link of the project repository. So, let's get started.

Why Real-time?

Real-time communication is a must-have for business because it enables faster, smoother, and more effective collaboration and communication among employees, customers, and partners. Real-time communication can improve the productivity, efficiency, and satisfaction of the business by providing the following benefits:

  • Seamless communication
  • Optimized business operations
  • Higher productivity and efficiency
  • Improved participation and knowledge sharing
  • Competitive advantage and innovation

But the question is, how to make it happen? the answer is:

WebSocket

WebSocket is a computer communications protocol that allows simultaneous two-way communication between a client and a server over a single TCP connection. WebSocket is different from the HTTP protocol, which is usually used for webpages, because it enables the server to send data to the client without waiting for a request and allows messages to be passed back and forth while keeping the connection open. This makes WebSocket suitable for real-time data transfer, such as chat applications, online games, or live streaming.

Socket.IO is a JavaScript library that I chose for building a real-time chat app using React, Context API, and Node.js. Socket.IO is based on WebSocket, but it provides additional features and benefits, such as:

Setting Up Socket.IO in the Project

First, create a socket directory in your project.

change directory to socket, and then do:

npm init --yes

npm install socket.io

After that, create the index.js file:

import { Server } from "socket.io";

const io = new Server({
cors: {
origin: "http://localhost:5173", //your client url
},
});

let onlineUsers = [];

io.on("connection", (socket) => {
// add user

socket.on("addNewUser", (userId) => {
!onlineUsers.some((user) => user.userId === userId) &&
onlineUsers.push({
userId,
socketId: socket.id,
});

console.log("Connected Users:", onlineUsers);

// send active users
io.emit("getUsers", onlineUsers);
});

// add message
socket.on("sendMessage", (message) => {
const user = onlineUsers.find(
(user) => user.userId === message.recipientId
);

if (user) {
console.log("sending message and notification");
io.to(user.socketId).emit("getMessage", message);
io.to(user.socketId).emit("getNotification", {
senderId: message.senderId,
isRead: false,
date: new Date(),
});
}
});

socket.on("disconnect", () => {
onlineUsers = onlineUsers.filter((user) => user.socketId !== socket.id);
console.log("User Disconnected:", onlineUsers);

// send active users
io.emit("getUsers", onlineUsers);
});
});

io.listen(3000);

Set Up the Client

in client directory, do:

npm install socket.io-client

then, modify the chat context start by importing the Socket.IO for client:

import { io } from "socket.io-client";

initialize the Socket.IO:

const [socket, setSocket] = useState(null);

useEffect(() => {
const newSocket = io("http://localhost:3000"); //your socket url
setSocket(newSocket);

return () => {
newSocket.disconnect();
};
}, [user]);

handle the real-time functionality:

// send message
useEffect(() => {
if (socket === null) return;

const recipientId = currentChat?.members.find((id) => id !== user?._id);

socket.emit("sendMessage", { ...newMessage, recipientId });
}, [newMessage]);

// receive message and notifications
useEffect(() => {
if (socket === null) return;

socket.on("getMessage", (res) => {
if (currentChat?._id !== res.chatId) return;

setMessages((prev) => [...prev, res]);
});

socket.on("getNotification", (res) => {
const isChatOpen = currentChat?.members.some((Id) => Id === res.senderId);

if (isChatOpen) {
setNotifications((prev) => [{ ...res, isRead: true }, ...prev]);
} else {
setNotifications((prev) => [res, ...prev]);
}
});

return () => {
socket.off("getMessage");
socket.off("getNotification");
};
}, [socket, currentChat]);

That way, we can now send and receive message in real-time.

Here’s the source code.

--

--