This commit is contained in:
cha0s 2024-09-18 01:32:26 -05:00
parent 946a06e78a
commit e2c0ec7638
4 changed files with 73 additions and 72 deletions

View File

@ -13,15 +13,9 @@ import { renderToPipeableStream } from "react-dom/server";
const ABORT_DELAY = 5_000; const ABORT_DELAY = 5_000;
export async function websocket(server, viteDevServer) { export async function handleUpgrade(request, socket, head) {
if (viteDevServer) { const {handleUpgrade} = await import('./server/websocket.js');
const {createViteRuntime} = await import('vite'); handleUpgrade(request, socket, head);
const runtime = await createViteRuntime(viteDevServer);
(await runtime.executeEntrypoint('/app/server/websocket.js')).default(server);
}
else {
(await import('./server/websocket.js')).default(server);
}
} }
export default function handleRequest( export default function handleRequest(

View File

@ -449,7 +449,13 @@ export default class Engine {
loop(); loop();
} }
stop() { async stop() {
const promises = [];
for (const [connection] of this.connectedPlayers) {
promises.push(this.disconnectPlayer(connection));
}
await Promise.all(promises);
await this.saveEcses();
clearTimeout(this.handle); clearTimeout(this.handle);
this.handle = undefined; this.handle = undefined;
} }

View File

@ -10,38 +10,7 @@ import Engine from './engine.js';
const isInsecure = process.env.SILPHIUS_INSECURE_HTTP; const isInsecure = process.env.SILPHIUS_INSECURE_HTTP;
const wss = new WebSocketServer({ global.__silphiusWebsocket = null;
noServer: true,
});
function onUpgrade(request, socket, head) {
const {pathname} = new URL(request.url, 'wss://base.url');
if (pathname === '/ws') {
wss.handleUpgrade(request, socket, head, function done(ws) {
wss.emit('connection', ws, request);
});
}
else {
socket.destroy();
}
}
let engine;
let onConnect;
function createOnConnect(engine) {
onConnect = async (ws, request) => {
ws.on('close', async () => {
await engine.disconnectPlayer(ws);
})
ws.on('message', (packed) => {
engine.server.accept(ws, new DataView(packed.buffer, packed.byteOffset, packed.length));
});
const session = await getSession(request.headers['cookie']);
await engine.connectPlayer(ws, session.get('id'));
};
wss.on('connection', onConnect);
}
class SocketServer extends Server { class SocketServer extends Server {
async ensurePath(path) { async ensurePath(path) {
@ -75,35 +44,55 @@ class SocketServer extends Server {
transmit(ws, packed) { ws.send(packed); } transmit(ws, packed) { ws.send(packed); }
} }
async function createEngine(Engine) { export async function handleUpgrade(request, socket, head) {
engine = new Engine(SocketServer); if (!global.__silphiusWebsocket) {
await engine.load(); const engine = new Engine(SocketServer);
engine.start(); await engine.load();
return engine; engine.start();
} const handleConnection = async (ws, request) => {
ws.on('close', async () => {
async function remakeServer(Engine) { await engine.disconnectPlayer(ws);
if (onConnect) { })
wss.off('connection', onConnect); ws.on('message', (packed) => {
engine.server.accept(ws, new DataView(packed.buffer, packed.byteOffset, packed.length));
});
const session = await getSession(request.headers['cookie']);
await engine.connectPlayer(ws, session.get('id'));
};
const wss = new WebSocketServer({
noServer: true,
});
wss.on('connection', handleConnection);
global.__silphiusWebsocket = {engine, handleConnection, wss};
} }
if (engine) { const {pathname} = new URL(request.url, 'wss://base.url');
for (const [connection] of engine.connectedPlayers) { if (pathname === '/ws') {
connection.close(); const {wss} = global.__silphiusWebsocket;
} wss.handleUpgrade(request, socket, head, function done(ws) {
wss.emit('connection', ws, request);
});
}
else {
socket.destroy();
} }
createOnConnect(await createEngine(Engine));
} }
(async () => {
await remakeServer(Engine);
})();
if (import.meta.hot) { if (import.meta.hot) {
import.meta.hot.accept('./engine.js', async ({default: Engine}) => { import.meta.hot.on('vite:beforeUpdate', async () => {
await remakeServer(Engine); if (global.__silphiusWebsocket) {
const {engine, handleConnection, wss} = global.__silphiusWebsocket;
wss.off('connection', handleConnection);
const connections = [];
for (const [connection] of engine.connectedPlayers) {
engine.server.send(connection, {type: 'EcsChange'});
connections.push(connection);
}
await engine.stop();
for (const connection of connections) {
connection.close();
}
global.__silphiusWebsocket = null;
}
}); });
} import.meta.hot.accept();
export default async function listen(server) {
server.on('upgrade', onUpgrade);
} }

View File

@ -61,11 +61,23 @@ const build = () => (
? viteDevServer.ssrLoadModule('virtual:remix/server-build') ? viteDevServer.ssrLoadModule('virtual:remix/server-build')
: import('./build/server/index.js') : import('./build/server/index.js')
); );
const ssr = await build(); let remixHandler;
await ssr.entry.module.websocket(server, viteDevServer); if (viteDevServer) {
const remixHandler = createRequestHandler({ const {createViteRuntime} = await import('vite');
build: () => ssr, const runtime = await createViteRuntime(viteDevServer);
}); const {handleUpgrade} = await runtime.executeEntrypoint('/app/server/websocket.js');
server.on('upgrade', handleUpgrade);
remixHandler = createRequestHandler({build});
}
else {
const ssr = await build();
server.on('upgrade', ssr.entry.module.handleUpgrade);
remixHandler = createRequestHandler({
build: async () => {
return ssr;
},
});
}
// configure middleware // configure middleware
app.use(compression()); app.use(compression());