lifetracker/apps/web/server.ts

87 lines
2.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// apps/web/server.js
import express from 'express';
import http from 'http';
import next from 'next';
import { WebSocketServer } from 'ws';
import { applyWSSHandler } from '@trpc/server/adapters/ws';
import { appRouter } from '@lifetracker/trpc/routers/_app';
import { createWSContext } from '@/server/api/ws';
import { parse } from 'url';
import { NextRequestHint } from 'next/dist/server/web/adapter';
const dev = process.env.NODE_ENV !== 'production';
// Create an Express app and HTTP server.
const app = express();
const server = http.createServer(app);
const nextApp = next({
dev,
customServer: true,
hostname: process.env.HOSTNAME || "localhost",
port: Number(process.env.PORT) || 3000,
});
const handle = nextApp.getRequestHandler();
nextApp.prepare().then(() => {
// Fallback to NextJS request handling for everything else.
app.all('*', (req: express.Request, res: express.Response) => {
return handle(req, res);
});
// Create a WebSocket server that shares the same HTTP server.
const wss = new WebSocketServer({
noServer: true,
path: '/api/ws',
});
// Attach the TRPC WebSocket handler.
const handler = applyWSSHandler({
wss,
router: appRouter,
createContext: createWSContext,
});
wss.on('connection', (ws) => {
console.log(` Got new websocket connection (now ${wss.clients.size})`);
ws.once('close', () => {
console.log(` Closed websocket connection (now ${wss.clients.size})`);
});
});
wss.on('error', function (error) {
console.log(error);
});
const port = process.env.PORT || 3000;
server.listen(port, () => {
console.log(`> Server listening on http://localhost:${port}`);
console.log(`> TRPC WebSocket server listening at ws://localhost:${port}/api/ws`);
});
app.all('*', (req: express.Request, res: express.Response) => {
return handle(req, res);
});
server.on('upgrade', (request, socket, head) => {
const { pathname } = parse(request.url!);
// Only handle WebSocket upgrades of the specific path(s) your application
// needs to handle
if (pathname === "/api/ws") {
wss.handleUpgrade(request, socket, head, function done(ws) {
console.log("Socket connected");
// At this point, you have the WebSocket in `ws`
// and the original HTTP request in `request` available
ws.send("Hello from Lifetracker!");
});
}
});
// Handle graceful shutdown.
process.on('SIGTERM', () => {
console.log('SIGTERM received, shutting down gracefully.');
handler.broadcastReconnectNotification();
server.close();
});
});