I am new to socket.io. I am working on a real-time notification feature using socket.io. Everything is working fine. But when reloading the browser the socketId of the user is changed and the notification feature is not working. My question is how to track the new socketId when the browser refresh.
//server.js-> socket.io code
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
},
});
let onlineUsers: any = [];
const addNewUser = (username: any, socketId: any) => {
!onlineUsers.some((user: any) => user.username === username) &&
onlineUsers.push({ username, socketId });
console.log("o", onlineUsers);
};
const getUser = (username: any) => {
return onlineUsers.find((user: any) => user.username === username);
};
io.on("connection", (socket) => {
console.log("a user connected");
console.log(socket.id);
socket.on("newUser", (username: any) => {
console.log("username", username);
// console.log("socketId", socket);
addNewUser(username, socket.id);
});
socket.on("sendNotification", ({ senderName, receiverName, action }) => {
const receiver = getUser(receiverName);
io.to(receiver?.socketId).emit("getNotification", {
senderName,
action,
});
});
socket.on("disconnect", () => {
console.log("user disconnected");
});
});
//client side socket.io code
useEffect(() => {
setSocket(io("http://localhost:5000"));
}, []);
useEffect(() => {
const userData: any = localStorage.getItem("user");
setUser(JSON.parse(userData)?.name);
// console.log("userId", userId, socket.emit);
if (user) {
socket?.emit("newUser", user);
}
}, [socket, user]);
//navbar component
React.useEffect(() => {
socket?.on("getNotification", (data: any) => {
console.log("data2", data);
setNotifications((prev): any => [...prev, data]);
});
}, [socket]);
Please try to elaborate on your answer/ suggestion or reference.
CodePudding user response:
I don't know if this is even possible in socket.io, it's supposed to get a new socket ID on refresh, but you could maybe do something with IP addresses? Maybe use one of these:
socket.handshake.headers["x-forwarded-for"], socket.handshake.headers["x-real-ip"], or socket.handshake.address.
you could keep an "ipmap" array and add these values to the map on connect and track users that way, because IP addresses don't change when you refresh your browser.
CodePudding user response:
I find out the solution to this problem. Probably this is not the perfect solution but work should be done. Explain the solution to others.
Actually, the problem was in this function
const addNewUser = (username: any, socketId: any) => {
!onlineUsers.some((user: any) => user.username === username) &&
onlineUsers.push({ username, socketId });
};
I wrote this function to avoid duplicate data in the onlineUsers
array. When I reload the browser, socketId
is changed but the username
is the same. So no data is pushed in the onlineUsers
array.
Now, I write this function instead of the above function
const addNewUser = (username: any, socketId: any) => {
if (onlineUsers.length === 0) {
onlineUsers.push({ username, socketId });
}
if (onlineUsers.length > 0) {
onlineUsers = onlineUsers.filter((user: any) => user.username !== username);
onlineUsers.push({ username, socketId });
}
};
Now new user data replace the same old user data in the onlineUsers
array and works fine after reloading.