Skip to content

Commit

Permalink
refactor: tried and failed to make ws work in prod
Browse files Browse the repository at this point in the history
  • Loading branch information
azaleacolburn committed Dec 8, 2024
1 parent c943642 commit 6e1dbe3
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 112 deletions.
Binary file modified bun.lockb
Binary file not shown.
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"scripts": {
"dev": "vite dev",
"build": "vite build",
"prod": "bun install && bun run build && node server.js && node ./build/index.js",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
Expand Down Expand Up @@ -32,8 +33,14 @@
"vite": "^5.4.11"
},
"dependencies": {
"@sveltejs/adapter-node": "^5.2.9",
"@types/node": "^22.10.1",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"http": "^0.0.1-security",
"lucide-svelte": "^0.460.1",
"socket.io": "^4.8.1",
"socket.io-client": "^4.8.1"
"socket.io-client": "^4.8.1",
"svelte-adapter-bun": "^0.5.2"
}
}
17 changes: 17 additions & 0 deletions server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var http_1 = require("http");
var express_1 = require("express");
var ws_1 = require("./ws");
var handler_js_1 = require("./build/handler.js");
var dotenv = require("dotenv");
dotenv.config();
var app = (0, express_1.default)();
var server = http_1.default.createServer(app);
// Inject SocketIO
(0, ws_1.default)(server);
// SvelteKit handlers
app.use(handler_js_1.handler);
server.listen(process.env.PUBLIC_WS_ENDPOINT, function () {
console.log('Running on http://localhost:' + PUBLIC_WS_ENDPOINT);
});
3 changes: 2 additions & 1 deletion src/routes/admin/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<script lang="ts">
import type { TeamMatch } from '$lib/types';
import { io, Socket } from 'socket.io-client';
import { PUBLIC_WS_ENDPOINT } from '$env/static/public';
let scout_queue: string[] = $state([]);
let robot_queue: string[] = $state([]);
let submitted_team_matches: TeamMatch[] = $state([]);
let socket: Socket = io({
let socket: Socket = io(PUBLIC_WS_ENDPOINT, {
auth: {
token: 'celary',
username: 'admin'
Expand Down
4 changes: 2 additions & 2 deletions src/routes/queue/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script lang="ts">
import { browser } from '$app/environment';
import { goto } from '$app/navigation';
import { io, Socket } from 'socket.io-client';
import { PUBLIC_WS_ENDPOINT } from '$env/static/public';
const username = 'test_scout';
let socket: Socket;
socket = io({
socket = io(PUBLIC_WS_ENDPOINT, {
auth: {
username
}
Expand Down
2 changes: 1 addition & 1 deletion svelte.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import adapter from '@sveltejs/adapter-auto';
import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
Expand Down
8 changes: 7 additions & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import webSocketServer from './ws.js';
import { webSocketServer } from './wsPlugin';

export default defineConfig({
server: {
port: 5173
},
preview: {
port: 5173
},
plugins: [sveltekit(), webSocketServer]
});
204 changes: 98 additions & 106 deletions ws.ts
Original file line number Diff line number Diff line change
@@ -1,133 +1,125 @@
import type { TeamMatch } from '$lib/types';
import { Server } from 'socket.io';
import { type ViteDevServer } from 'vite';
import { type HttpServer } from 'vite';
const info = (s: string) => console.log(`\x1b[32m ${s} \x1b[0m`);

const sid_to_username: Map<string, string> = new Map();
const robot_queue: [string, 'red' | 'blue'][] = [];
let curr_match_key: string = '';

const webSocketServer = {
name: 'webSocketServer',
configureServer(server: ViteDevServer) {
if (!server.httpServer) return;
const io = new Server(server.httpServer);
export default function injectSocketIO(server: HttpServer) {
const io = new Server(server);

io.use((socket, next) => {
const username = socket.handshake.auth.username;
if (!username) {
return next(new Error('invalid username'));
}
io.use((socket, next) => {
const username = socket.handshake.auth.username;
if (!username) {
return next(new Error('invalid username'));
}

let old_entries = sid_to_username.entries().find(([_key, value]) => value == username);
if (old_entries) {
old_entries
.map(([key, _value]) => key)
.forEach((key) => sid_to_username.delete(key));
}
let old_entries = sid_to_username.entries().find(([_key, value]) => value == username);
if (old_entries) {
old_entries.map(([key, _value]) => key).forEach((key) => sid_to_username.delete(key));
}

sid_to_username.set(socket.id, username);

sid_to_username.set(socket.id, username);
next();
});

next();
io.on('connect', (socket) => {
if (socket.handshake.auth.token === 'celary') {
info('Admin Aquired');
socket.join('admin_room');
}

socket.emit('session', {
session_id: socket.id
});

io.on('connect', (socket) => {
if (socket.handshake.auth.token === 'celary') {
info('Admin Aquired');
socket.join('admin_room');
socket.on('join_queue', () => {
const username = sid_to_username.get(socket.id);

const team_data = robot_queue.pop();
if (!team_data) {
io.to('admin_room').emit('scout_joined_queue', username);
socket.join('scout_queue');
return;
}
io.to('admin_room').emit('robot_left_queue', team_data);
socket.emit('time_to_scout', [curr_match_key, ...team_data]);
});

socket.emit('session', {
session_id: socket.id
});
socket.on('leave_scout_queue', (scout_id: string) => {
const scout_sid = sid_to_username
.entries()
.filter(([_sid, scout]) => scout === scout_id)
.map(([sid, _]) => sid)
.toArray()[0];
console.log(scout_sid);
// This event exist in the cast that the scout removed itself from the queue
io.emit('scout_left_queue', scout_id);
// This event exists in the case that the admin removed the scout from the queue
// io.to(scout_sid).emit('you_left_queue');
io.sockets.sockets.get(scout_sid)?.leave('scout_queue');
});

socket.on('join_queue', () => {
const username = sid_to_username.get(socket.id);
socket.on('leave_robot_queue', (robot: string) => {
const index = robot_queue.findIndex(([id, _color]) => id === robot);
if (index === -1) return;

const team_data = robot_queue.pop();
if (!team_data) {
io.to('admin_room').emit('scout_joined_queue', username);
socket.join('scout_queue');
return;
}
io.to('admin_room').emit('robot_left_queue', team_data);
socket.emit('time_to_scout', [curr_match_key, ...team_data]);
});

socket.on('leave_scout_queue', (scout_id: string) => {
const scout_sid = sid_to_username
.entries()
.filter(([_sid, scout]) => scout === scout_id)
.map(([sid, _]) => sid)
.toArray()[0];
console.log(scout_sid);
// This event exist in the cast that the scout removed itself from the queue
io.emit('scout_left_queue', scout_id);
// This event exists in the case that the admin removed the scout from the queue
// io.to(scout_sid).emit('you_left_queue');
io.sockets.sockets.get(scout_sid)?.leave('scout_queue');
});

socket.on('leave_robot_queue', (robot: string) => {
const index = robot_queue.findIndex(([id, _color]) => id === robot);
if (index === -1) return;

robot_queue.splice(index, 1);
});

socket.on(
'send_match',
async ([match_key, teams]: [string, [string, 'red' | 'blue'][]]) => {
if (!socket.rooms.has('admin_room')) return;

const scout_queue = await io.in('scout_queue').fetchSockets();
for (const socket of scout_queue) {
const team_data = teams.pop();
if (!team_data) break;

const username = sid_to_username.get(socket.id);
if (!username) {
console.error('Scout in queue not in map');
continue;
}

socket.leave('scout_queue');
socket.emit('time_to_scout', [match_key, ...team_data]);
io.to('admin_room').emit('scout_left_queue', username);
}
robot_queue.splice(index, 1);
});

socket.emit(
'robot_joined_queue',
teams.map(([team, _color]) => team)
);
robot_queue.push(...teams);
socket.on(
'send_match',
async ([match_key, teams]: [string, [string, 'red' | 'blue'][]]) => {
if (!socket.rooms.has('admin_room')) return;

// Update all connected sockets with new match info (for cosmetic purposes)
io.emit('new_match', match_key);
curr_match_key = match_key;
}
);
const scout_queue = await io.in('scout_queue').fetchSockets();
for (const socket of scout_queue) {
const team_data = teams.pop();
if (!team_data) break;

// Event-listener sockets that were offline to sync back up with the current match key
socket.on('request_curr_match', () => {
socket.emit('new_match', curr_match_key);
});
const username = sid_to_username.get(socket.id);
if (!username) {
console.error('Scout in queue not in map');
continue;
}

socket.on('remove_team_match', (team_match: TeamMatch) => {
if (!socket.rooms.has('admin_room')) return;
socket.leave('scout_queue');
socket.emit('time_to_scout', [match_key, ...team_data]);
io.to('admin_room').emit('scout_left_queue', username);
}

info(
`TeamMatch: ${team_match.match_key}_${team_match.team_key} was removed by the admin`
socket.emit(
'robot_joined_queue',
teams.map(([team, _color]) => team)
);
// TODO: Emit message from the db to remove team_match
});
robot_queue.push(...teams);

// Update all connected sockets with new match info (for cosmetic purposes)
io.emit('new_match', match_key);
curr_match_key = match_key;
}
);

socket.on('submit_team_match', (team_match: TeamMatch) => {
console.log('log match');
io.to('admin_room').emit('new_team_match', team_match);
});
// Event-listener sockets that were offline to sync back up with the current match key
socket.on('request_curr_match', () => {
socket.emit('new_match', curr_match_key);
});
}
};

export default webSocketServer;
socket.on('remove_team_match', (team_match: TeamMatch) => {
if (!socket.rooms.has('admin_room')) return;

info(
`TeamMatch: ${team_match.match_key}_${team_match.team_key} was removed by the admin`
);
// TODO: Emit message from the db to remove team_match
});

socket.on('submit_team_match', (team_match: TeamMatch) => {
console.log('log match');
io.to('admin_room').emit('new_team_match', team_match);
});
});
}
10 changes: 10 additions & 0 deletions wsPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { type ViteDevServer } from 'vite';
import injectServer from './ws';

export const webSocketServer = {
name: 'webSocketServer',
configureServer(server: ViteDevServer) {
if (!server.httpServer) return;
injectServer(server.httpServer);
}
};

0 comments on commit 6e1dbe3

Please sign in to comment.