Skip to content
Draft
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
77 changes: 2 additions & 75 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,76 +1,3 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
node_modules
dist
.env

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless

# FuseBox cache
.fusebox/
83 changes: 0 additions & 83 deletions main.js

This file was deleted.

12 changes: 12 additions & 0 deletions render.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
services:
- name: websocket-server
type: web
runtime: node
buildCommand: npm install
startCommand: node server.js
plan: free
envVars:
- key: NODE_ENV
value: production
- key: PORT
value: 3001
115 changes: 115 additions & 0 deletions server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import express from 'express';
import { WebSocketServer, WebSocket } from 'ws';
import { createServer } from 'http';

const app = express();
const server = createServer(app);
const wss = new WebSocketServer({
server,
// Add CORS headers for WebSocket
verifyClient: (info, cb) => {
const origin = info.origin || info.req.headers.origin;
cb(true); // Accept all origins in development
}
});

// Enable CORS for Express
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});

const rooms = new Map();

function heartbeat() {
this.isAlive = true;
}

wss.on('connection', (ws) => {
console.log('Client connected');
let currentRoom = null;

ws.isAlive = true;
ws.on('pong', heartbeat);

ws.on('message', (message) => {
try {
const data = JSON.parse(message.toString());
console.log('Received message:', data);

switch (data.type) {
case 'create':
currentRoom = data.room;
console.log('Creating room:', currentRoom);
if (!rooms.has(currentRoom)) {
rooms.set(currentRoom, new Set());
}
rooms.get(currentRoom).add(ws);
ws.send(JSON.stringify({ type: 'connected' }));
break;

case 'join':
currentRoom = data.room;
console.log('Joining room:', currentRoom);
if (rooms.has(currentRoom)) {
rooms.get(currentRoom).add(ws);
ws.send(JSON.stringify({ type: 'connected' }));
}
break;

case 'transcript':
if (currentRoom && rooms.has(currentRoom)) {
console.log('Broadcasting transcript in room:', currentRoom);
rooms.get(currentRoom).forEach((client) => {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify({
type: 'transcript',
text: data.text
}));
}
});
}
break;
}
} catch (error) {
console.error('Error processing message:', error);
}
});

ws.on('close', () => {
console.log('Client disconnected from room:', currentRoom);
if (currentRoom && rooms.has(currentRoom)) {
rooms.get(currentRoom).delete(ws);
if (rooms.get(currentRoom).size === 0) {
rooms.delete(currentRoom);
}
}
});

ws.on('error', (error) => {
console.error('WebSocket error:', error);
});
});

const interval = setInterval(() => {
wss.clients.forEach((ws) => {
if (ws.isAlive === false) {
console.log('Terminating inactive client');
return ws.terminate();
}

ws.isAlive = false;
ws.ping();
});
}, 30000);

wss.on('close', () => {
clearInterval(interval);
});

const PORT = process.env.PORT || 3001;
server.listen(PORT, () => {
console.log(`WebSocket server is running on port ${PORT}`);
});
10 changes: 10 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "ES6",
"module": "CommonJS",
"outDir": "./dist",
"rootDir": "./",
"strict": true
}
}