diff --git a/src/helper.ts b/src/helper.ts new file mode 100644 index 0000000..2ccd95b --- /dev/null +++ b/src/helper.ts @@ -0,0 +1,39 @@ +export function getSecsFromDates(date: Date): number { + const timestamp1 = date.getTime(); // Timestamp in milliseconds + const timestamp2 = new Date().getTime(); // Timestamp in milliseconds + + // Calculate the difference in milliseconds + const differenceInMs = timestamp2 - timestamp1; + + // Convert to seconds + const differenceInSeconds = differenceInMs / 1000; + + console.log(`Difference in seconds: ${differenceInSeconds}`); + return Math.floor(differenceInSeconds); +} + +export async function saveCallLogs(callLog: { + from: string; + to: string; + time: number; +}) { + const { from, to, time } = callLog; + console.log("saveCallLogs", callLog); + try { + const res = await fetch( + "https://multiplyyapi.convexsol.com/Investor/CreateCallLogs", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ from, to, time }), + } + ); + if (!res.ok) { + console.log("Failed to save call logs"); + } + } catch (error) { + console.log("saveCallLogs", error); + } +} diff --git a/src/index.ts b/src/index.ts index adfa560..4628e22 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,7 @@ import { createServer, Server as HTTPServer } from "http"; import { Server as SocketIOServer, Socket } from "socket.io"; import cors from "cors"; import { + activeCallMapType, callRequestAReject, ConnectRequest, OnlineUser, @@ -11,14 +12,17 @@ import { rtcOffer, UserDetails, } from "./types/sType.js"; +import { getSecsFromDates, saveCallLogs } from "./helper"; // Initialize Express const app = express(); // Set up CORS middleware for Express -app.use(cors({ - origin: "*", -})); +app.use( + cors({ + origin: "*", + }) +); // Create an HTTP server const httpServer: HTTPServer = createServer(app); @@ -34,6 +38,11 @@ const io = new SocketIOServer(httpServer, { // Store online users const onlineUsers: Map = new Map(); +// Remap the socket ID to the user ID +const socketToUserId: Map = new Map(); + +//call request +const activeCalls: activeCallMapType = new Map(); // Handle WebSocket connections io.on("connection", (socket: Socket) => { @@ -49,6 +58,7 @@ io.on("connection", (socket: Socket) => { image, socketId: socket.id, }); + socketToUserId.set(socket.id, userId); }); // Handle connect request event @@ -84,10 +94,57 @@ io.on("connection", (socket: Socket) => { }); // Handle user disconnect event - socket.on("disconnect", () => { - const userArr = Array.from(onlineUsers.values()); - const u = userArr.filter((item: any) => item.socketId == socket.id); - onlineUsers.delete(u[0].userId); + socket.on("disconnect", async () => { + const user = activeCalls.get(socket.id); + console.log("disconnect", user); + if (user) { + if (user?.from) { + const calleeU = socketToUserId.get(socket.id); + const callerU = socketToUserId.get(user.from); + if (calleeU && callerU) { + const caller = onlineUsers.get(callerU); + const callee = onlineUsers.get(calleeU); + if (caller && callee) { + const meetTime = getSecsFromDates(user.callTime); + const callLog = { + to: callee.userId, + from: caller.userId, + time: meetTime, + }; + await saveCallLogs(callLog); + socket.to(caller.socketId).emit("call-rejected"); + } + } + } + if (user?.to) { + const callerU = socketToUserId.get(socket.id); + const calleeU = socketToUserId.get(user.to); + if (calleeU && callerU) { + const caller = onlineUsers.get(callerU); + const callee = onlineUsers.get(calleeU); + if (caller && callee) { + const meetTime = getSecsFromDates(user.callTime); + const callLog = { + to: callee.userId, + from: caller.userId, + time: meetTime, + }; + await saveCallLogs(callLog); + socket.to(callee.socketId).emit("call-rejected"); + } + } + } + const secUser = user?.to || user?.from; + if (secUser) { + activeCalls.delete(socket.id); + activeCalls.delete(secUser); + } + } + const userId = socketToUserId.get(socket.id); + if (userId) { + onlineUsers.delete(userId); + socketToUserId.delete(socket.id); + } }); // Handle user ice candidate event @@ -128,19 +185,68 @@ io.on("connection", (socket: Socket) => { // // Handle call-accept events socket.on("call-accept", (data: callRequestAReject) => { - const { to } = data; + const { to, from } = data; const calledTo = onlineUsers.get(to); - if (calledTo) { + const calledFrom = onlineUsers.get(from); + if (calledTo && calledFrom) { + activeCalls.set(calledFrom.socketId, { + to: calledTo.socketId, + callTime: new Date(), + }); + activeCalls.set(calledTo.socketId, { + from: calledFrom.socketId, + callTime: new Date(), + }); + console.log("call-accept", activeCalls); socket.to(calledTo.socketId).emit("call-accepted"); } }); // // Handle call-reject events - socket.on("call-reject", (data: callRequestAReject) => { - const { to } = data; - const calledTo = onlineUsers.get(to); - if (calledTo) { - socket.to(calledTo.socketId).emit("call-rejected"); + socket.on("call-reject", async () => { + const user = activeCalls.get(socket.id); + if (user) { + if (user?.from) { + const calleeU = socketToUserId.get(socket.id); + const callerU = socketToUserId.get(user.from); + if (calleeU && callerU) { + const caller = onlineUsers.get(callerU); + const callee = onlineUsers.get(calleeU); + if (caller && callee) { + const meetTime = getSecsFromDates(user.callTime); + const callLog = { + to: callee.userId, + from: caller.userId, + time: meetTime, + }; + await saveCallLogs(callLog); + socket.to(caller.socketId).emit("call-rejected"); + } + } + } + if (user?.to) { + const callerU = socketToUserId.get(socket.id); + const calleeU = socketToUserId.get(user.to); + if (calleeU && callerU) { + const caller = onlineUsers.get(callerU); + const callee = onlineUsers.get(calleeU); + if (caller && callee) { + const meetTime = getSecsFromDates(user.callTime); + const callLog = { + to: callee.userId, + from: caller.userId, + time: meetTime, + }; + await saveCallLogs(callLog); + socket.to(callee.socketId).emit("call-rejected"); + } + } + } + const secUser = user?.to || user?.from; + if (secUser) { + activeCalls.delete(socket.id); + activeCalls.delete(secUser); + } } }); }); diff --git a/src/types/he b/src/types/he new file mode 100644 index 0000000..e69de29 diff --git a/src/types/sType.ts b/src/types/sType.ts index 56df95b..ac52d53 100644 --- a/src/types/sType.ts +++ b/src/types/sType.ts @@ -33,4 +33,10 @@ export type rtcCandidate = { export type callRequestAReject = { to: string; + from: string; }; + +export type activeCallMapType = Map< + string, + { to?: string; from?: string; callTime: Date } +>;