frontend-app / server /socket.js
Keys
fixes
2ecbb66
import { Server as SocketIOServer } from "socket.io";
import Message from "./model/MessagesModel.js";
import Channel from "./model/ChannelModel.js";
const setupSocket = (server) => {
const io = new SocketIOServer(server, {
cors: {
origin: process.env.ORIGIN,
methods: ["GET", "POST"],
credentials: true,
},
});
const userSocketMap = new Map();
const addChannelNotify = async (channel) => {
if (channel && channel.members) {
channel.members.forEach((member) => {
const memberSocketId = userSocketMap.get(member.toString());
if (memberSocketId) {
io.to(memberSocketId).emit("new-channel-added", channel);
}
});
}
};
const sendMessage = async (message) => {
const recipientSocketId = userSocketMap.get(message.recipient);
const senderSocketId = userSocketMap.get(message.sender);
// Create the message
const createdMessage = await Message.create(message);
// Find the created message by its ID and populate sender and recipient details
const messageData = await Message.findById(createdMessage._id)
.populate("sender", "id email firstName lastName image color")
.populate("recipient", "id email firstName lastName image color")
.exec();
if (recipientSocketId) {
io.to(recipientSocketId).emit("receiveMessage", messageData);
}
// Optionally, send the message back to the sender (e.g., for message confirmation)
if (senderSocketId) {
io.to(senderSocketId).emit("receiveMessage", messageData);
}
};
const sendChannelMessage = async (message) => {
const { channelId, sender, content, messageType, fileUrl } = message;
// Create and save the message
const createdMessage = await Message.create({
sender,
recipient: null, // Channel messages don't have a single recipient
content,
messageType,
timestamp: new Date(),
fileUrl,
});
const messageData = await Message.findById(createdMessage._id)
.populate("sender", "id email firstName lastName image color")
.exec();
// Add message to the channel
await Channel.findByIdAndUpdate(channelId, {
$push: { messages: createdMessage._id },
});
// Fetch all members of the channel
const channel = await Channel.findById(channelId).populate("members");
const finalData = { ...messageData._doc, channelId: channel._id };
if (channel && channel.members) {
channel.members.forEach((member) => {
const memberSocketId = userSocketMap.get(member._id.toString());
if (memberSocketId) {
io.to(memberSocketId).emit("recieve-channel-message", finalData);
}
});
const adminSocketId = userSocketMap.get(channel.admin._id.toString());
if (adminSocketId) {
io.to(adminSocketId).emit("recieve-channel-message", finalData);
}
}
};
const disconnect = (socket) => {
console.log("Client disconnected", socket.id);
for (const [userId, socketId] of userSocketMap.entries()) {
if (socketId === socket.id) {
userSocketMap.delete(userId);
break;
}
}
};
io.on("connection", (socket) => {
const userId = socket.handshake.query.userId;
if (userId) {
userSocketMap.set(userId, socket.id);
console.log(`User connected: ${userId} with socket ID: ${socket.id}`);
} else {
console.log("User ID not provided during connection.");
}
socket.on("add-channel-notify", addChannelNotify);
socket.on("sendMessage", sendMessage);
socket.on("send-channel-message", sendChannelMessage);
socket.on("disconnect", () => disconnect(socket));
});
};
export default setupSocket;