1+ import { availableParallelism } from 'node:os' ;
2+ import cluster from 'node:cluster' ;
3+ import { createServer } from 'node:http' ;
4+ import { fileURLToPath } from 'node:url' ;
5+ import { dirname , join } from 'node:path' ;
6+ import express from 'express' ;
7+ import { createAdapter , setupPrimary } from '@socket.io/cluster-adapter' ;
8+ import { Server } from 'socket.io' ;
9+ import createLogger from './src/logger.js' ;
10+ import createConfig from './src/config/config-mgr.js' ;
11+ import createDB from './src/db.js' ;
12+
13+ /**
14+ * The logger instance
15+ *
16+ */
17+ const logger = createLogger ( 'server' ) ;
18+ /**
19+ * Configuration instance
20+ *
21+ */
22+ const config = await createConfig ( ) ;
23+ /**
24+ * Database connection instance
25+ *
26+ */
27+ const database = await createDB ( config ) ;
28+
29+ /**
30+ * The main entry point of the application
31+ * if the clusters are enabled, the primary process will fork the workers
32+ * otherwise, the server will run in a single process
33+ */
34+ if ( cluster . isPrimary && config . clusters ) {
35+ const numCPUs = availableParallelism ( ) ;
36+ database . init ( ) ;
37+ for ( let i = 0 ; i < numCPUs ; i ++ ) {
38+ cluster . fork ( {
39+ PORT : config . basePort + i
40+ } ) ;
41+ }
42+ setupPrimary ( ) ;
43+ } else {
44+
45+ const app = express ( ) ;
46+ const server = createServer ( app ) ;
47+ const io = new Server ( server , {
48+ connectionStateRecovery : { } ,
49+ adapter : createAdapter ( )
50+ } ) ;
51+
52+ const __dirname = dirname ( fileURLToPath ( import . meta. url ) ) ;
53+
54+ app . get ( '/' , ( req , res ) => {
55+ res . sendFile ( join ( __dirname , 'html/index.html' ) ) ;
56+ } ) ;
57+
58+ io . on ( 'connection' , async ( socket ) => {
59+ logger . debug ( 'new user connected' ) ;
60+ io . emit ( 'connection' , "new user connected" ) ;
61+ socket . on ( 'chat message' , async ( nickname , msg , clientOffset , callback ) => {
62+ logger . chat ( nickname , msg ) ;
63+ const result = database . insertMessage ( nickname , msg , clientOffset ) ;
64+ io . emit ( 'chat message' , nickname , msg , result . lastID ) ;
65+ callback ( ) ;
66+ socket . on ( 'disconnect' , ( ) => {
67+ io . emit ( 'connection' , "user disconnected" ) ;
68+ logger . debug ( 'user disconnected' ) ;
69+ } ) ;
70+ } ) ;
71+
72+ if ( ! socket . recovered ) {
73+ logger . debug ( 'socket not recovered' ) ;
74+ database . retreiveMesaages ( ( nickname , msg , id ) => {
75+ socket . emit ( 'chat message' , nickname , msg , id ) ;
76+ } ) ;
77+ }
78+ } ) ;
79+
80+ server . listen ( process . env . PORT , ( ) => {
81+ logger . highlight ( `Running at http://localhost:${ process . env . PORT } ` ) ;
82+ } ) . on ( 'error' , ( e ) => {
83+ logger . error ( 'Error starting server' , e ) ;
84+ } ) ;
85+ }
0 commit comments