-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathserver.js
More file actions
139 lines (113 loc) · 3.96 KB
/
server.js
File metadata and controls
139 lines (113 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import compression from 'compression';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import dotenv from 'dotenv';
import { createServer } from 'http';
import { WebSocketServer } from 'ws';
// Import our custom modules
import { setupRoutes } from './src/routes/index.js';
import { initializeServices } from './src/services/index.js';
import { setupWebSocket } from './src/websocket/chatSocket.js';
import { rateLimiter } from './src/middleware/rateLimiter.js';
import { errorHandler } from './src/middleware/errorHandler.js';
import { logger } from './src/utils/logger.js';
// Load environment variables
dotenv.config();
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
class RAGChatbotServer {
constructor() {
this.app = express();
this.server = createServer(this.app);
this.wss = new WebSocketServer({ server: this.server });
this.port = process.env.PORT || 3000;
}
async initialize() {
try {
// Initialize services
await initializeServices();
// Setup middleware
this.setupMiddleware();
// Setup routes
this.setupRoutes();
// Setup WebSocket
this.setupWebSocket();
// Setup error handling
this.setupErrorHandling();
logger.info('Server initialized successfully');
} catch (error) {
logger.error('Failed to initialize server:', error);
process.exit(1);
}
}
setupMiddleware() {
// Security middleware
this.app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'", "https://cdnjs.cloudflare.com"],
scriptSrc: ["'self'", "'unsafe-inline'", "https://cdnjs.cloudflare.com"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'", "ws:", "wss:"],
},
},
}));
// CORS configuration
this.app.use(cors({
origin: process.env.CORS_ORIGIN || 'http://localhost:3000',
credentials: true
}));
// Compression
this.app.use(compression());
// Body parsing
this.app.use(express.json({ limit: '50mb' }));
this.app.use(express.urlencoded({ extended: true, limit: '50mb' }));
// Rate limiting
this.app.use(rateLimiter);
// Static files
this.app.use(express.static(join(__dirname, 'public')));
// Request logging
this.app.use((req, res, next) => {
logger.info(`${req.method} ${req.path} - ${req.ip}`);
next();
});
}
setupRoutes() {
setupRoutes(this.app);
}
setupWebSocket() {
setupWebSocket(this.wss);
}
setupErrorHandling() {
this.app.use(errorHandler);
}
async start() {
await this.initialize();
this.server.listen(this.port, () => {
logger.info(`🤖 RAG Q&A Chatbot Server running on port ${this.port}`);
logger.info(`🌐 Open your browser to: http://localhost:${this.port}`);
logger.info(`📚 Upload documents and start chatting!`);
});
// Graceful shutdown
process.on('SIGTERM', () => this.shutdown());
process.on('SIGINT', () => this.shutdown());
}
shutdown() {
logger.info('Shutting down server...');
this.server.close(() => {
logger.info('Server closed');
process.exit(0);
});
}
}
// Start the server
const server = new RAGChatbotServer();
server.start().catch(error => {
logger.error('Failed to start server:', error);
process.exit(1);
});
export default server;