From 2357e4492362c69d923e976849c2db7fcdc5eb3e Mon Sep 17 00:00:00 2001 From: Zoe <62722391+juls0730@users.noreply.github.com> Date: Tue, 2 Sep 2025 23:36:13 -0500 Subject: [PATCH] various fixes and additions, files, but fixed, code cleanup etc --- server/websocketHandler.ts | 51 +++++++++++++++++++++-------- src/components/RTCMessage.svelte | 56 ++++++++++++++++++++++++++++---- src/utils/webrtcUtil.ts | 17 ++++++++-- 3 files changed, 101 insertions(+), 23 deletions(-) diff --git a/server/websocketHandler.ts b/server/websocketHandler.ts index e3a9f67..a030b49 100644 --- a/server/websocketHandler.ts +++ b/server/websocketHandler.ts @@ -1,4 +1,3 @@ -import { json } from "@sveltejs/kit"; import { WebSocketServer } from "ws"; import type { WebSocket } from "ws"; @@ -6,14 +5,20 @@ import type { WebSocket } from "ws"; const rooms = new Map(); enum MessageType { + // requests CREATE_ROOM = 'create', JOIN_ROOM = 'join', + + // responses ROOM_CREATED = 'created', ROOM_JOINED = 'joined', ROOM_READY = 'ready', + + // webrtc ICE_CANDIDATE = 'ice-candidate', OFFER = 'offer', ANSWER = 'answer', + ERROR = 'error', } @@ -24,27 +29,50 @@ type Message = { function createRoom(socket: WebSocket): string { let roomId = Math.random().toString(36).substring(2, 10); - rooms.set(roomId, [socket]); + rooms.set(roomId, []); + + socket.send(JSON.stringify({ type: MessageType.ROOM_CREATED, data: roomId })); + + joinRoom(roomId, socket); return roomId; } function joinRoom(roomId: string, socket: WebSocket) { - const room = rooms.get(roomId); + let room = rooms.get(roomId); + console.log(room?.length); // should be unreachable if (!room) { throw new Error(`Room ${roomId} does not exist`); } + if (room.length == 2) { + socket.send(JSON.stringify({ type: MessageType.ERROR, data: 'Room is full' })); + return; + } + // notify all clients in the room of the new client, except the client itself room.forEach(client => { client.send(JSON.stringify({ type: MessageType.JOIN_ROOM, data: roomId })); }); room.push(socket); - // the client is now in the room and the peer knows about it - socket.send(JSON.stringify({ type: MessageType.ROOM_JOINED, data: null })); + socket.addEventListener('close', (ev) => { + room = rooms.get(roomId) + if (!room) { + return; + } + + // for some reason, when you filter the array when the length is 1 it stays at 1, but we *know* that if its 1 + // then when this client disconnects, the room should be deleted since the room is empty + if (room.length === 1) { + deleteRoom(roomId); + return; + } + + rooms.set(roomId, room.filter(client => client !== ev.target)); + }); // TODO: consider letting rooms get larger than 2 clients if (room.length == 2) { @@ -63,8 +91,6 @@ export function confgiureWebsocketServer(ws: WebSocketServer) { ws.on('connection', socket => { // Handle messages from the client socket.on('message', event => { - console.log(event, typeof event); - let message; if (event instanceof Buffer) { // Assuming JSON is sent as a string @@ -92,8 +118,7 @@ export function confgiureWebsocketServer(ws: WebSocketServer) { switch (type) { case MessageType.CREATE_ROOM: // else, create a new room - const roomId = createRoom(socket); - socket.send(JSON.stringify({ type: MessageType.ROOM_CREATED, data: roomId })); + createRoom(socket); break; case MessageType.JOIN_ROOM: // if join message has a roomId, join the room @@ -109,6 +134,9 @@ export function confgiureWebsocketServer(ws: WebSocketServer) { } joinRoom(message.data, socket); + + // the client is now in the room and the peer knows about it + socket.send(JSON.stringify({ type: MessageType.ROOM_JOINED, data: null })); break; case MessageType.OFFER: case MessageType.ANSWER: @@ -130,10 +158,5 @@ export function confgiureWebsocketServer(ws: WebSocketServer) { break; } }); - - // Handle client disconnection - socket.on('close', () => { - // TODO: if this client was in a room, remove them from the room - }); }); } \ No newline at end of file diff --git a/src/components/RTCMessage.svelte b/src/components/RTCMessage.svelte index 35cd64d..3f59129 100644 --- a/src/components/RTCMessage.svelte +++ b/src/components/RTCMessage.svelte @@ -10,6 +10,8 @@ } from "../utils/webrtcUtil"; let inputMessage: Writable = writable(""); + let inputFile = writable(null); + let inputFileElement: HTMLInputElement; function sendMessage() { if (!$peer) { @@ -17,13 +19,29 @@ return; } - $messages = [...$messages, `You: ${$inputMessage}`]; - $peer.send($inputMessage); - $inputMessage = ""; + if (!$inputFile && !$inputMessage) { + return; + } + + if ($inputFile != null && $inputFile[0] !== undefined) { + $messages = [...$messages, `You: ${$inputFile[0].name}`]; + $peer.send($inputFile[0]); + $inputFile = null; + } + + if ($inputMessage) { + $messages = [...$messages, `You: ${$inputMessage}`]; + $peer.send($inputMessage); + $inputMessage = ""; + } + } + + function pickFile() { + inputFileElement.click(); } -{#if $room && $connected} +{#if $room !== null && $connected === true} {#if !$isRTCConnected}

Waiting for peer to connect...

{:else if !$dataChannelReady} @@ -34,7 +52,12 @@

{msg}

{/each} - +
+
{/if} -{:else} -

Waiting for peer to connect...

{/if} diff --git a/src/utils/webrtcUtil.ts b/src/utils/webrtcUtil.ts index e7c040d..ac6d486 100644 --- a/src/utils/webrtcUtil.ts +++ b/src/utils/webrtcUtil.ts @@ -15,8 +15,23 @@ const callbacks = { console.log("Connected to peer"); isRTCConnected.set(true); }, + //! TODO: come up with a more complex room system. This is largely for testing purposes onMessage: (message: string | ArrayBuffer) => { console.log("Received message:", message); + if (typeof message === 'object' && message instanceof Blob) { + // download the file + const url = URL.createObjectURL(message); + const a = document.createElement('a'); + a.href = url; + a.download = message.name; + document.body.appendChild(a); + a.click(); + setTimeout(() => { + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + }, 100); + } + messages.set([...get(messages), `Peer: ${message}`]); }, onDataChannelOpen: () => { @@ -67,8 +82,6 @@ export async function handleMessage(event: MessageEvent) { await get(peer)?.createOffer(); } return; - default: - console.warn(`Unknown message type: ${message.type}`); } if (!get(peer)) {