-
Notifications
You must be signed in to change notification settings - Fork 464
Expand file tree
/
Copy pathproduction-final.js
More file actions
176 lines (140 loc) · 4.68 KB
/
production-final.js
File metadata and controls
176 lines (140 loc) · 4.68 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
* 最终的生产环境启动文件
* 分离Next.js和WebSocket服务器,避免任何冲突
*/
process.env.NODE_ENV = 'production';
const path = require('path');
const http = require('http');
// 调用 generate-manifest.js 生成 manifest.json
function generateManifest() {
console.log('Generating manifest.json for Docker deployment...');
try {
const generateManifestScript = path.join(
__dirname,
'scripts',
'generate-manifest.js'
);
require(generateManifestScript);
} catch (error) {
console.error('❌ Error calling generate-manifest.js:', error);
throw error;
}
}
// 生成manifest
generateManifest();
// 启动独立的WebSocket服务器
const { createStandaloneWebSocketServer, getOnlineUsers, sendMessageToUsers } = require('./standalone-websocket');
const wsPort = process.env.WS_PORT || 3001;
const wss = createStandaloneWebSocketServer(wsPort);
// 将WebSocket函数存储到全局对象,供API路由使用
global.getOnlineUsers = getOnlineUsers;
global.sendMessageToUsers = sendMessageToUsers;
// 启动Next.js standalone服务器
console.log('Starting Next.js production server...');
const nextServerPath = path.join(__dirname, 'server.js');
// 检查是否存在standalone server.js
const fs = require('fs');
if (fs.existsSync(nextServerPath)) {
// Docker环境,使用standalone server
require(nextServerPath);
} else {
// 非Docker环境,使用标准Next.js启动
const { createServer } = require('http');
const { parse } = require('url');
const next = require('next');
const hostname = process.env.HOSTNAME || '0.0.0.0';
const port = process.env.PORT || 3000;
const app = next({
dev: false,
hostname,
port
});
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = createServer(async (req, res) => {
try {
const parsedUrl = parse(req.url, true);
await handle(req, res, parsedUrl);
} catch (err) {
console.error('处理请求时出错:', req.url, err);
res.statusCode = 500;
res.end('内部服务器错误');
}
});
server.listen(port, (err) => {
if (err) throw err;
console.log(`> Next.js服务已启动: http://${hostname}:${port}`);
setupServerTasks();
});
});
}
// 设置服务器启动后的任务
function setupServerTasks() {
const httpPort = process.env.PORT || 3000;
const hostname = process.env.HOSTNAME || 'localhost';
// 每1秒轮询一次,直到请求成功
const TARGET_URL = `http://${hostname}:${httpPort}/login`;
const intervalId = setInterval(() => {
console.log(`Fetching ${TARGET_URL} ...`);
const req = http.get(TARGET_URL, (res) => {
// 当返回2xx状态码时认为成功,然后停止轮询
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
console.log('Server is up, stop polling.');
clearInterval(intervalId);
setTimeout(() => {
// 服务器启动后,立即执行一次cron任务
executeCronJob();
}, 3000);
// 然后设置每小时执行一次cron任务
setInterval(() => {
executeCronJob();
}, 60 * 60 * 1000); // 每小时执行一次
// 显示服务状态
console.log('====================================');
console.log(`✅ Next.js服务运行在: http://${hostname}:${httpPort}`);
console.log(`✅ WebSocket服务运行在: ws://${hostname}:${wsPort}`);
console.log('====================================');
}
});
req.setTimeout(2000, () => {
req.destroy();
});
req.on('error', () => {
// 忽略连接错误,继续轮询
});
}, 1000);
}
// 执行cron任务的函数
function executeCronJob() {
const httpPort = process.env.PORT || 3000;
const hostname = process.env.HOSTNAME || 'localhost';
const cronUrl = `http://${hostname}:${httpPort}/api/cron`;
console.log(`Executing cron job: ${cronUrl}`);
const req = http.get(cronUrl, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
console.log('Cron job executed successfully:', data);
} else {
console.error('Cron job failed:', res.statusCode, data);
}
});
});
req.on('error', (err) => {
console.error('Error executing cron job:', err);
});
req.setTimeout(30000, () => {
console.error('Cron job timeout');
req.destroy();
});
}
// 如果直接运行此文件,设置任务
if (require.main === module) {
// 延迟启动任务,等待服务器完全启动
setTimeout(() => {
setupServerTasks();
}, 5000);
}