Skip to content
Open
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
27,475 changes: 0 additions & 27,475 deletions backend/logs/combined.log

This file was deleted.

2,133 changes: 0 additions & 2,133 deletions backend/logs/error.log

This file was deleted.

2 changes: 2 additions & 0 deletions backend/src/controllers/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export const me = async (request: Request, response: Response) => {
message: "User not found"
});
}

logger.info('[USER]', user)

return response.status(200).json({
success: true,
Expand Down
2 changes: 1 addition & 1 deletion backend/src/mediasoup/transport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const createWebRtcTransport = async (
transport.on("icestatechange", (iceState) => {
const info = transportRegistry.get(transport.id);

logger.info("Transport ICE state changed", {
logger.info(`Transport ICE state changed: ${iceState}`, {
event: "TRANSPORT_ICE_STATE_CHANGE",
transportId: transport.id,
roomId: info?.roomId,
Expand Down
2 changes: 1 addition & 1 deletion backend/src/utils/disconnect.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const handleDisconnect = async(socket: Socket) => {
removeViewer(roomId,socket.id)
await dbCleanUp(socket.id)
}else if(!broadcaster || !viewer){
logger.warn('IDK')
logger.warn('Not a broadcaster not a viewer')
}
}

Expand Down
1 change: 0 additions & 1 deletion backend/src/utils/roomCordinator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Server } from "socket.io";
import { RedisRoom } from "../types/mediasoup";
import logger from "./logging";
import { redis } from "./redis.util";
Expand Down
1 change: 1 addition & 0 deletions backend/src/utils/socket.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ io.on("connection", (socket) => {
})

socket.on("disconnect", async (reason) => {
logger.info('[REASON]', reason)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This debug line is redundant and does not show the value it intends to. The winston customFormat in logging.ts renders only the message, so the reason passed as the second argument is discarded and the log prints just '[REASON]'. The very next line already logs the reason. Remove this line and rely on the existing disconnect log.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At backend/src/utils/socket.util.ts, line 144:

<comment>This debug line is redundant and does not show the value it intends to. The winston customFormat in logging.ts renders only the message, so the `reason` passed as the second argument is discarded and the log prints just '[REASON]'. The very next line already logs the reason. Remove this line and rely on the existing disconnect log.</comment>

<file context>
@@ -141,6 +141,7 @@ io.on("connection", (socket) => {
   })
 
   socket.on("disconnect", async (reason) => {
+    logger.info('[REASON]', reason)
     logger.info(`User disconnected ${socket.id} beacuse of ${reason}`)
     handleDisconnect(socket)
</file context>

logger.info(`User disconnected ${socket.id} beacuse of ${reason}`)
handleDisconnect(socket)
await stopFfmpegRecording(socket.id)
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/components/viewer/ViewerVideo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ export default function ViewerVideo({
playsInline
controls={false}
className="h-full w-full object-cover"
onPlaying={() => {
if (!window.__csFirstFrameAt) {
window.__csFirstFrameAt = Date.now();
console.log("[LOAD TEST] First video frame playing");
}
}}
/>

{!connected && (
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/pages/Broadcaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ import SystemLogs from "../components/broadcaster/SystemLogs";
import LiveChat from "../components/broadcaster/LiveChat";
import ReactionOverlay from "../components/reactions/ReactionOverlay";

declare global {
interface Window {
__csRoomId?: string;
__csLiveAt?: number;
}
}

interface Log {
message: string;
timestamp: Date;
Expand Down Expand Up @@ -58,6 +65,7 @@ export default function BroadcasterPage() {
const room = await broadcaster.createRoom();

setRoomId(room.id);
window.__csRoomId = room.id

log("Fetching RTP capabilities...");

Expand All @@ -84,6 +92,7 @@ export default function BroadcasterPage() {
await broadcaster.startProducing(stream);

setIsLive(true);
window.__csLiveAt = Date.now();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The test hooks are write-only: stopBroadcast() clears roomId/isLive state but leaves window.__csRoomId and window.__csLiveAt set. If the broadcast flow is ever run twice on a page that isn't reloaded (stop then Go live again), waitForFunction(Boolean(window.__csLiveAt)) in load-test/media-fanout-capacity.js resolves instantly from the stale flag and falsely reports LIVE before media is actually flowing, producing a misleading fan-out result. Clear both globals in stopBroadcast().

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/src/pages/Broadcaster.tsx, line 95:

<comment>The test hooks are write-only: `stopBroadcast()` clears `roomId`/`isLive` state but leaves `window.__csRoomId` and `window.__csLiveAt` set. If the broadcast flow is ever run twice on a page that isn't reloaded (stop then Go live again), `waitForFunction(Boolean(window.__csLiveAt))` in load-test/media-fanout-capacity.js resolves instantly from the stale flag and falsely reports LIVE before media is actually flowing, producing a misleading fan-out result. Clear both globals in `stopBroadcast()`.</comment>

<file context>
@@ -84,6 +92,7 @@ export default function BroadcasterPage() {
       await broadcaster.startProducing(stream);
 
       setIsLive(true);
+      window.__csLiveAt = Date.now();
 
       log("Broadcast started successfully.");
</file context>


log("Broadcast started successfully.");
} catch (err: any) {
Expand Down Expand Up @@ -258,6 +267,7 @@ export default function BroadcasterPage() {
{!isLive ? (
<button
onClick={startBroadcast}
id="live-start-button"
className="flex items-center gap-1.5 rounded-xl bg-[#3fcf9e] px-4 py-2 text-sm font-semibold text-[#04241a] transition hover:bg-[#5fdcb2]"
>
<Play size={15} /> Go live
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/pages/ViewerPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ import LiveChat from "../components/broadcaster/LiveChat";
import ReactionOverlay from "../components/reactions/ReactionOverlay";
import { getSocket,startHeartBeat } from "../socket";

declare global {
interface Window {
__csJoinedAt?: number;
__csFirstFrameAt?: number;
}
}

interface Log {
message: string;
timestamp: Date;
Expand Down Expand Up @@ -61,6 +68,7 @@ export default function ViewerPage() {
log("Joining room...");

const caps = await viewer.joinRoom(roomId);
window.__csJoinedAt = Date.now();

log("Loading MediaSoup device...");

Expand Down
6 changes: 3 additions & 3 deletions frontend/src/router/ProtectedRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Navigate, Outlet } from "react-router-dom";
import { useEffect , useState} from "react";
import { connectSocket, disconnectSocket } from "../socket";

Check warning on line 3 in frontend/src/router/ProtectedRoute.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this unused import of 'disconnectSocket'.

See more on https://sonarcloud.io/project/issues?id=Harxhit_CrowdStream&issues=AaBTtue5cp18kkeMHel2&open=AaBTtue5cp18kkeMHel2&pullRequest=78
import useAuth from "../hooks/useAuth";

export default function ProtectedRoute() {
Expand All @@ -19,9 +19,9 @@
})
}

return () => {
disconnectSocket();
};
// return () => {
// disconnectSocket();
// };
Comment on lines +22 to +24

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: When ProtectedRoute unmounts, the singleton socket stays connected and the server does not run its disconnect cleanup; this also leaves disconnectSocket unused, so the configured TypeScript build fails. Restore the effect cleanup instead of commenting it out.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/src/router/ProtectedRoute.tsx, line 22:

<comment>When `ProtectedRoute` unmounts, the singleton socket stays connected and the server does not run its disconnect cleanup; this also leaves `disconnectSocket` unused, so the configured TypeScript build fails. Restore the effect cleanup instead of commenting it out.</comment>

<file context>
@@ -19,9 +19,9 @@ export default function ProtectedRoute() {
-    return () => {
-      disconnectSocket();
-    };
+    // return () => {
+    //   disconnectSocket();
+    // };
</file context>
Suggested change
// return () => {
// disconnectSocket();
// };
return () => {
disconnectSocket();
};

}, [authenticated]);

if (loading) {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export function connectSocket() {
}

socket = io(window.location.origin);
(window as any).__csSocket = socket;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This exposes the internal Socket.IO instance on window.__csSocket for every visitor, purely so load-test/media-fanout-capacity.js can reach it. In production this pollutes the global namespace and hands any injected or third-party script a fully-connected authenticated socket. Gate the test hook behind a build/run env check (e.g. if (import.meta.env.DEV || import.meta.env.VITE_ENABLE_TEST_HOOK)) so it ships only in test runs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/src/socket.ts, line 14:

<comment>This exposes the internal Socket.IO instance on window.__csSocket for every visitor, purely so load-test/media-fanout-capacity.js can reach it. In production this pollutes the global namespace and hands any injected or third-party script a fully-connected authenticated socket. Gate the test hook behind a build/run env check (e.g. `if (import.meta.env.DEV || import.meta.env.VITE_ENABLE_TEST_HOOK)`) so it ships only in test runs.</comment>

<file context>
@@ -11,6 +11,7 @@ export function connectSocket() {
     }
 
     socket = io(window.location.origin);
+    (window as any).__csSocket = socket;
 
     socket.on("connect", () => {
</file context>
Suggested change
(window as any).__csSocket = socket;
if (import.meta.env.DEV || import.meta.env.VITE_ENABLE_TEST_HOOK) {
(window as any).__csSocket = socket;
}


socket.on("connect", () => {
console.log("Client connected", socket?.id);
Expand Down
8 changes: 8 additions & 0 deletions load-test/media-fanout-100.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
timestamp,viewers,joinP50,joinP99,firstFrameP50,firstFrameP99,meanBitrateKbps,meanLossPct,meanFps,failures
2026-08-30T17:12:22.422Z,10,1546,1868,2914,3069,444.2,0.00,11.0,0
2026-08-30T17:12:46.401Z,20,1244,1796,2057,2789,440.4,0.00,10.3,0
2026-08-30T17:13:11.969Z,30,1808,2069,2540,3342,458.6,0.00,9.6,0
2026-08-30T17:13:39.728Z,40,2122,2878,3025,4370,442.0,0.00,9.4,0
2026-08-30T17:14:13.420Z,50,3691,4669,5507,6757,430.4,0.00,9.5,0
2026-08-30T17:14:54.392Z,60,5122,6769,6866,9592,262.1,0.00,10.2,0
2026-08-30T17:15:45.218Z,70,6853,8490,8529,10358,105.7,0.00,7.8,0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This results file is committed as realistic capacity data under a PR titled "real media-plane fan-out capacity test", yet the author's own PR description states the results were never run against a live backend and are a placeholder. The rows read as established findings — 0.00% loss/0 failures at every load step even as bitrate collapses 444→105 kbps and first-frame P99 reaches ~10.3s at 70 viewers — and the filename media-fanout-100.csv implies 100-viewer capacity while the data (and the in-repo results doc) only reach 70. A future reader will cite these as measured capacity and the 100-viewer ceiling. Non-zero loss/failures would normally appear at the observed degradation point, so the all-zero metrics are not self-evidently measured. Run the test against a live backend and commit the real numbers, or clearly mark the file (and results doc) as placeholder data so it is not mistaken for a real capacity finding.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At load-test/media-fanout-100.csv, line 8:

<comment>This results file is committed as realistic capacity data under a PR titled "real media-plane fan-out capacity test", yet the author's own PR description states the results were never run against a live backend and are a placeholder. The rows read as established findings — 0.00% loss/0 failures at every load step even as bitrate collapses 444→105 kbps and first-frame P99 reaches ~10.3s at 70 viewers — and the filename media-fanout-100.csv implies 100-viewer capacity while the data (and the in-repo results doc) only reach 70. A future reader will cite these as measured capacity and the 100-viewer ceiling. Non-zero loss/failures would normally appear at the observed degradation point, so the all-zero metrics are not self-evidently measured. Run the test against a live backend and commit the real numbers, or clearly mark the file (and results doc) as placeholder data so it is not mistaken for a real capacity finding.</comment>

<file context>
@@ -0,0 +1,8 @@
+2026-08-30T17:13:39.728Z,40,2122,2878,3025,4370,442.0,0.00,9.4,0
+2026-08-30T17:14:13.420Z,50,3691,4669,5507,6757,430.4,0.00,9.5,0
+2026-08-30T17:14:54.392Z,60,5122,6769,6866,9592,262.1,0.00,10.2,0
+2026-08-30T17:15:45.218Z,70,6853,8490,8529,10358,105.7,0.00,7.8,0
\ No newline at end of file
</file context>

Loading