Skip to content

Commit

Permalink
Merge pull request #159 from a0uda/ChatsFeature
Browse files Browse the repository at this point in the history
Updated the sockets section in the chats feature and tested with a sample frontend file.
  • Loading branch information
FatemaKotb authored May 4, 2024
2 parents a955bbe + f71ae58 commit 3ce9116
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 40 deletions.
5 changes: 3 additions & 2 deletions src/services/chatService.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,17 @@ const sendMessage = async (sender, receiverUsername, message) => {
}
}

let savedChat, savedMessage;
try {
const [savedChat, savedMessage] = await Promise.all([chat.save(), newMessage.save()]);
[savedChat, savedMessage] = await Promise.all([chat.save(), newMessage.save()]);
} catch (error) {
return { err: { status: 500, message: 'An error occurred while saving the chat or message' } };
}

const receiverSocketId = getReceiverSocketId(receiver._id);
if (receiverSocketId) {
// io.to(<socket_id>).emit() used to send events to specific client
io.to(receiverSocketId).emit("newMessage", newMessage);
io.to(receiverSocketId).emit("newMessage", savedMessage);
}

return { newMessage };
Expand Down
98 changes: 60 additions & 38 deletions src/socket/socket.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Server } from "socket.io";
import http from "http";
import express from "express";
import { stat } from "fs";
import jwt from "jsonwebtoken";
import { User } from "../db/models/User.js";

const io = require("socket.io")(Server, {
path: "/socket.io",
Expand All @@ -14,44 +17,63 @@ const io = require("socket.io")(Server, {

// // TODO: Uncomment.

// // This line creates a new Socket.IO server that uses the HTTP server.
// // It also sets up Cross-Origin Resource Sharing (CORS) to allow requests from "http://localhost:3000" using the GET and POST methods.

// // const io = new Server(server, {
// // cors: {
// // origin: ["http://localhost:2998", "http://localhost:2999", "http://localhost:3000"],
// // methods: ["GET", "POST", "PUT", "PATCH","DELETE"],
// // },
// // });

// const io = new Server(server)

// // This function is exported so it can be used in other files.
// // It takes a receiverId and returns the corresponding socket ID from userSocketMap.
// export const getReceiverSocketId = (receiverId) => {
// return userSocketMap[receiverId];
// };

// // This object maps user IDs to socket IDs.
// // It's used to keep track of which socket belongs to which user.
// const userSocketMap = {}; // {userId: socketId}

// // This sets up an event listener for the "connection" event, which is emitted whenever a client connects to the server.
// // Inside the event listener, it logs the socket ID,
// // stores the socket ID in userSocketMap if the user ID is defined,
// // and sets up an event listener for the "disconnect" event.
// io.on("connection", (socket) => {
// console.log("a user connected", socket.id);

// const userId = socket.handshake.query.userId;
// if (userId != "undefined") userSocketMap[userId] = socket.id;

// // socket.on() is used to listen to the events. can be used both on client and server side
// socket.on("disconnect", () => {
// console.log("user disconnected", socket.id);
// delete userSocketMap[userId];
// });
// });
const io = new Server(server, {
cors: {
origin: "*",
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"],
},
});


// This function is exported so it can be used in other files.
// It takes a receiverId and returns the corresponding socket ID from userSocketMap.
export const getReceiverSocketId = (receiverId) => {
return userSocketMap[receiverId];
};

// This object maps user IDs to socket IDs.
// It's used to keep track of which socket belongs to which user.
const userSocketMap = {}; // {user_id: socketId}

// This sets up an event listener for the "connection" event, which is emitted whenever a client connects to the server.
// Inside the event listener, it logs the socket ID,
// stores the socket ID in userSocketMap if the user ID is defined,
// and sets up an event listener for the "disconnect" event.
io.on("connection", async (socket) => {
console.log("a user connected", socket.id);

// Get the user from the procided token to fill the userSocketMap.

// Extract the token from the query parameter.
const token = socket.handshake.query.token.split(" ")[1];

// Verify the token.
let user_token;

try {
user_token = jwt.verify(token, process.env.JWT_SECRET);
} catch (err) {
console.log({ err: { status: 401, message: `Invalid Token: ${err.message}` } });
}

// Get the user id from the token.
const user_id = user_token._id;

// Get the user from the id.
const user = await User.findById(user_id);

if (!user) {
console.log({ err: { status: 404, message: "User not found" } });
} else {
userSocketMap[user_id] = socket.id;
}

// socket.on() is used to listen to the events. can be used both on client and server side
socket.on("disconnect", () => {
console.log("user disconnected", socket.id);
delete userSocketMap[user_id];
});
});

// export { app, io, server };

Expand Down

0 comments on commit 3ce9116

Please sign in to comment.