// M5 on a live server F: does a WebSocket through the openresty hold an hour? // One person in a fresh project, with /sync (the document) and /sim (the // room) open and nothing to say — the proxy's limit is between two bytes, // so only the pings of F (/sim, 30 s) and Hocuspocus (/sync) keep them. Every // five minutes a line; at the end a probe through /sim and a change through // /sync, to show that both still carry. // // npx vite-node tools/live/m5.ts [minutes] import { cleanUp, joinDoc, newProject, openRoom, signIn } from './lib.js'; const minutes = Number(process.argv[2] ?? 65); const started = Date.now(); const elapsed = () => `${((Date.now() - started) / 60_000).toFixed(1)} min`; try { const project = await newProject(); const cookie = await signIn(project, { name: 'Dauer' }); const shared = await joinDoc(project, cookie); const room = await openRoom(project, cookie); let syncClosed = ''; shared.provider.on('close', ({ event }: { event: { code: number; reason: string } }) => (syncClosed ||= `${event.code} ${event.reason} at ${elapsed()}`)); let simClosed = ''; void room.closed.then((reason) => (simClosed = `${reason} at ${elapsed()}`)); console.log(`open: /sync and /sim, holding ${minutes} min`); for (let minute = 5; minute <= minutes; minute += 5) { await new Promise((resolve) => setTimeout(resolve, Math.min(5, minutes - minute + 5) * 60_000)); console.log(`${elapsed()}: /sync ${syncClosed || 'open'}, /sim ${simClosed || 'open'}`); } room.send({ kind: 'input', node: 'probe', app: 'terminal', action: 'enter', args: { line: '' }, reqId: 'last' }); const answer = await room .waitFor((message) => message.reqId === 'last', 10_000) .then( () => 'answered', () => 'no answer', ); shared.doc.getMap('meta').set('m5', Date.now()); const stored = await new Promise((resolve) => { const end = Date.now() + 10_000; const look = () => (shared.provider.unsyncedChanges === 0 ? resolve('stored') : Date.now() > end ? resolve('not stored') : setTimeout(look, 50)); look(); }); console.log(`after ${elapsed()}: /sim probe ${answer}, /sync change ${stored}; closed: /sync ${syncClosed || 'never'}, /sim ${simClosed || 'never'}`); room.close(); shared.close(); } finally { await cleanUp(); }