|
|
- import express, { Request, Response } from "express";
- import { createServer, Server as HTTPServer } from "http";
- import { Server as SocketIOServer, Socket } from "socket.io";
- import cors from "cors";
- import {
- activeCallMapType,
- callRequestAReject,
- ConnectRequest,
- OnlineUser,
- rtcAnswer,
- rtcCandidate,
- 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: "*",
- })
- );
-
- // Create an HTTP server
- const httpServer: HTTPServer = createServer(app);
-
- // Initialize Socket.io on the server
- const io = new SocketIOServer(httpServer, {
- path: "/socket", // Define the WebSocket path
- cors: {
- origin: "*", // Update this to the origin of your client
- methods: ["GET", "POST"],
- },
- });
-
- // Store online users
- const onlineUsers: Map<string, OnlineUser> = new Map();
- // Remap the socket ID to the user ID
- const socketToUserId: Map<string, string> = new Map();
-
- //call request
- const activeCalls: activeCallMapType = new Map();
-
- // Handle WebSocket connections
- io.on("connection", (socket: Socket) => {
- console.log("User connected", socket.id);
-
- // Handle user-online event
- socket.on("user-online", (user: UserDetails) => {
- const { userId, userName, image } = user;
- // Now we store the socket ID along with the user details
- onlineUsers.set(userId, {
- userId: userId,
- userName,
- image,
- socketId: socket.id,
- });
- socketToUserId.set(socket.id, userId);
- });
-
- // Handle connect request event
- socket.on("connect-req", (user: ConnectRequest) => {
- const { caller, callee, userName, image } = user;
- // Now we store the socket ID along with the user details
- const details = onlineUsers.get(String(callee));
- console.log("connect-req", details, onlineUsers, user);
- if (details) {
- socket.to(details.socketId).emit("connect-res", {
- userId: caller,
- userName,
- image,
- time: new Date(),
- });
- }
- });
-
- // Handle user-online event
- socket.on("connect-reject-req", (data: { users: number[] }) => {
- const { users } = data;
- console.log("connect-reject-req", data);
- // Now we store the socket ID along with the user details
- for (const user of users) {
- const details = onlineUsers.get(String(user));
- console.log("connect-reject-req", details);
- if (details) {
- socket.to(details.socketId).emit("connect-reject-res", {
- reject: true,
- });
- }
- }
- });
-
- // Handle user disconnect event
- 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
- socket.on("ice-candidate", (data: rtcCandidate) => {
- const { candidate, to } = data;
- const calledTo = onlineUsers.get(to);
- if (calledTo) {
- console.log("get-ice-candidate", to);
- // Emit to the recipient's socket ID
- socket.to(calledTo.socketId).emit("get-ice-candidate", candidate);
- }
- });
-
- // // Handle call-offer events
- socket.on("offer", (data: rtcOffer) => {
- const { offer, to, sender } = data;
- const calledFrom = onlineUsers.get(sender);
- const calledTo = onlineUsers.get(to);
- if (calledTo && calledFrom) {
- // Emit to the recipient's socket ID
- socket.to(calledTo.socketId).emit("get-offer", {
- offer,
- sender: sender,
- senderName: calledFrom.userName,
- senderImage: calledFrom.image,
- });
- }
- });
-
- // // Handle call-request events
- socket.on("call-request", (data: rtcAnswer) => {
- const { answer, to } = data;
- const calledTo = onlineUsers.get(to);
- if (calledTo) {
- socket.to(calledTo.socketId).emit("get-answer", answer);
- }
- });
-
- // // Handle call-accept events
- socket.on("call-accept", (data: callRequestAReject) => {
- const { to, from } = data;
- const calledTo = onlineUsers.get(to);
- 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", 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);
- }
- }
- });
- });
-
- app.use(express.json());
-
- // Define a basic route
- app.get("/", (req: Request, res: Response) => {
- res.send("WebSocket server is running");
- });
-
- // Define a basic route
- app.post("/get-onlines", (req: Request, res: Response) => {
- const { users }: { users: number[] } = req.body;
- const onlineUsersData = users.filter((user: number) =>
- onlineUsers.has(String(user))
- );
- res.json({ users: onlineUsersData });
- });
-
- // Start the server on port 3000
- const PORT = process.env.PORT || 5007;
- httpServer.listen(PORT, () => {
- console.log(`Server is running on port ${PORT}`);
- });
|