Skip to content
Open
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
97 changes: 15 additions & 82 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,84 +1,17 @@
import express from 'express';
import { createServer } from 'node:http';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { createServer } from 'http';
import { Server } from 'socket.io';
import sqlite3 from 'sqlite3';
import { open } from 'sqlite';
import { availableParallelism } from 'node:os';
import cluster from 'node:cluster';
import { createAdapter, setupPrimary } from '@socket.io/cluster-adapter';

if (cluster.isPrimary) {
const numCPUs = availableParallelism();
for (let i = 0; i < numCPUs; i++) {
cluster.fork({
PORT: 3000 + i
});
}

setupPrimary();
} else {
const db = await open({
filename: 'chat.db',
driver: sqlite3.Database
});

await db.exec(`
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
client_offset TEXT UNIQUE,
content TEXT
);
`);

const app = express();
const server = createServer(app);
const io = new Server(server, {
connectionStateRecovery: {},
adapter: createAdapter()
});

const __dirname = dirname(fileURLToPath(import.meta.url));

app.get('/', (req, res) => {
res.sendFile(join(__dirname, 'index.html'));
});

io.on('connection', async (socket) => {
socket.on('chat message', async (msg, clientOffset, callback) => {
let result;
try {
result = await db.run('INSERT INTO messages (content, client_offset) VALUES (?, ?)', msg, clientOffset);
} catch (e) {
if (e.errno === 19 /* SQLITE_CONSTRAINT */ ) {
callback();
} else {
// nothing to do, just let the client retry
}
return;
}
io.emit('chat message', msg, result.lastID);
callback();
});

if (!socket.recovered) {
try {
await db.each('SELECT id, content FROM messages WHERE id > ?',
[socket.handshake.auth.serverOffset || 0],
(_err, row) => {
socket.emit('chat message', row.content, row.id);
}
)
} catch (e) {
// something went wrong
}
}
});

const port = process.env.PORT;

server.listen(port, () => {
console.log(`server running at http://localhost:${port}`);
});
}
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const app = express();
const server = createServer(app);
const io = new Server(server);
app.get('/', (req,res)=> res.sendFile(path.join(__dirname,'index.html')));
let users=[];
io.on('connection', s=>{
s.on('join', d=>{ s.data=d; s.join(d.room); users.push({id:s.id,name:d.name,role:d.role}); io.emit('users',users); });
s.on('chat message', d=>{ io.to(d.room).emit('chat message',{name:s.data.name,text:d.text,role:s.data.role}); });
s.on('disconnect',()=>{ users=users.filter(u=>u.id!=s.id); io.emit('users',users); });
});
server.listen(process.env.PORT||3000);