Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsc",
"dev": "nodemon dist/server.js"
"dev": "node server.js",
"dev-ts": "node --loader ts-node/esm src/server.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module",
"dependencies": {
"bcryptjs": "^3.0.2",
"cors": "^2.8.5",
"dotenv": "^17.2.3",
"express": "^5.1.0",
"jsonwebtoken": "^9.0.2",
Expand Down
68 changes: 68 additions & 0 deletions backend/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import mongoose from "mongoose";
import { createServer } from "http";
import { Server as SocketIOServer } from "socket.io";
import express from "express";
import dotenv from "dotenv";
import cors from "cors";

dotenv.config();

const app = express();
const PORT = process.env.PORT || 3000;
const MONGO_URI = process.env.MONGO_URI || "mongodb://localhost:27017/peercall";

app.use(express.json());
app.use(cors());

const chatMessages = [];

const httpServer = createServer(app);
const io = new SocketIOServer(httpServer, {
cors: { origin: "*" },
});

io.on("connection", (socket) => {
console.log("User connected:", socket.id);

socket.on("join-room", (roomId, userName) => {
socket.join(roomId);
console.log(`${userName} joined room ${roomId}`);
const roomMessages = chatMessages.filter(msg => msg.roomId === roomId);
socket.emit("chat-history", roomMessages.slice(-50));
});

socket.on("chat-message", ({ roomId, user, text }) => {
const message = {
roomId,
user,
text,
time: new Date(),
id: Date.now()
};
chatMessages.push(message);
io.to(roomId).emit("chat-message", message);
console.log(`Message in ${roomId} from ${user}: ${text}`);
});

socket.on("disconnect", () => {
console.log("User disconnected:", socket.id);
});
});

app.get("/health", (req, res) => {
res.json({ status: "OK", message: "Chat server is running" });
});

httpServer.listen(PORT, () => {
console.log(`🚀 Chat server running on port ${PORT}`);
console.log(`📡 Socket.io ready for real-time chat`);
console.log(`💬 Chat overlay feature is active!`);
});

process.on('SIGINT', () => {
console.log('\n🛑 Shutting down chat server...');
httpServer.close(() => {
console.log('✅ Server closed');
process.exit(0);
});
});
17 changes: 17 additions & 0 deletions backend/src/models/chatMessageModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import mongoose, { Document, Schema } from "mongoose";

export interface IChatMessage extends Document {
roomId: string;
user: string;
text: string;
timestamp: Date;
}

const chatMessageSchema = new Schema<IChatMessage>({
roomId: { type: String, required: true },
user: { type: String, required: true },
text: { type: String, required: true },
timestamp: { type: Date, default: Date.now },
});

export const ChatMessage = mongoose.model<IChatMessage>("ChatMessage", chatMessageSchema);
43 changes: 42 additions & 1 deletion backend/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import mongoose from "mongoose";
import { createServer } from "http";
import { Server as SocketIOServer } from "socket.io";
import app from "./app.js"
import { ChatMessage } from "./models/chatMessageModel.js";

import dotenv from "dotenv";
dotenv.config();
Expand All @@ -8,10 +11,48 @@ const PORT = process.env.PORT;
const MONGO_URI = process.env.MONGO_URI as string;
// console.log(MONGO_URI)

const httpServer = createServer(app);
const io = new SocketIOServer(httpServer, {
cors: { origin: "*" },
});

io.on("connection", (socket) => {
socket.on("join-room", async (roomId, userName) => {
socket.join(roomId);
// Send recent chat history to the user
try {
const recentMessages = await ChatMessage.find({ roomId })
.sort({ timestamp: -1 })
.limit(50)
.lean();
socket.emit("chat-history", recentMessages.reverse());
} catch (error) {
console.error("Error fetching chat history:", error);
}
});

socket.on("chat-message", async ({ roomId, user, text }) => {
try {
// Save message to database
const message = new ChatMessage({ roomId, user, text });
await message.save();

// Broadcast to all users in the room
io.to(roomId).emit("chat-message", {
user,
text,
time: new Date(),
});
} catch (error) {
console.error("Error saving message:", error);
}
});
});

mongoose
.connect(MONGO_URI)
.then(() => {
console.log(" MongoDB Connected");
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
httpServer.listen(PORT, () => console.log(`Server running on port ${PORT}`));
})
.catch((err) => console.error(" DB connection failed:", err));
Loading
Loading