- 更新服务器端文件上传处理逻辑,避免重复发送事件 - 客户端优化文件上传组件,防止重复添加文件 - 调整文件列表更新策略,支持文件更新 - 优化上传区域样式,提升用户体验
137 lines
4.2 KiB
JavaScript
137 lines
4.2 KiB
JavaScript
const { createServer } = require('http');
|
|
const { parse } = require('url');
|
|
const next = require('next');
|
|
const { Server } = require('socket.io');
|
|
|
|
const dev = process.env.NODE_ENV !== 'production';
|
|
const hostname = 'localhost';
|
|
const port = parseInt(process.env.PORT || '3000', 10);
|
|
const socketPort = parseInt(process.env.SOCKET_PORT || '3001', 10);
|
|
|
|
// Create Next.js app
|
|
const app = next({ dev, hostname, port });
|
|
const handler = app.getRequestHandler();
|
|
|
|
// Create HTTP server for socket events
|
|
const httpServer = createServer((req, res) => {
|
|
const url = parse(req.url, true);
|
|
|
|
if (url.pathname === '/file:uploaded' && req.method === 'POST') {
|
|
let body = '';
|
|
req.on('data', chunk => {
|
|
body += chunk.toString();
|
|
});
|
|
req.on('end', () => {
|
|
try {
|
|
const fileData = JSON.parse(body);
|
|
io.emit('file:uploaded', fileData);
|
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ success: true }));
|
|
} catch (error) {
|
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ success: false, error: 'Invalid data' }));
|
|
}
|
|
});
|
|
} else if (url.pathname === '/file:deleted' && req.method === 'POST') {
|
|
let body = '';
|
|
req.on('data', chunk => {
|
|
body += chunk.toString();
|
|
});
|
|
req.on('end', () => {
|
|
try {
|
|
const data = JSON.parse(body);
|
|
io.emit('file:deleted', data);
|
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ success: true }));
|
|
} catch (error) {
|
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ success: false, error: 'Invalid data' }));
|
|
}
|
|
});
|
|
} else if (url.pathname === '/file:visibility:changed' && req.method === 'POST') {
|
|
let body = '';
|
|
req.on('data', chunk => {
|
|
body += chunk.toString();
|
|
});
|
|
req.on('end', () => {
|
|
try {
|
|
const data = JSON.parse(body);
|
|
io.emit('file:visibility:changed', data);
|
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ success: true }));
|
|
} catch (error) {
|
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ success: false, error: 'Invalid data' }));
|
|
}
|
|
});
|
|
} else {
|
|
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ success: false, error: 'Not found' }));
|
|
}
|
|
});
|
|
|
|
// Create Socket.IO server
|
|
const io = new Server(httpServer, {
|
|
cors: {
|
|
origin: process.env.NEXTAUTH_URL || `http://${hostname}:${port}`,
|
|
methods: ['GET', 'POST'],
|
|
},
|
|
});
|
|
|
|
let userCount = 0;
|
|
|
|
io.on('connection', (socket) => {
|
|
userCount++;
|
|
io.emit('user:count', userCount);
|
|
console.log(`User connected. Total users: ${userCount}`);
|
|
|
|
// Handle file upload events (from client)
|
|
socket.on('file:upload', (data) => {
|
|
socket.broadcast.emit('file:uploaded', data);
|
|
console.log('File uploaded:', data.filename);
|
|
});
|
|
|
|
// Handle file delete events (from client)
|
|
socket.on('file:delete', (data) => {
|
|
socket.broadcast.emit('file:deleted', data);
|
|
console.log('File deleted:', data.id);
|
|
});
|
|
|
|
// Handle file visibility toggle events (from client)
|
|
socket.on('file:toggle:visibility', (data) => {
|
|
socket.broadcast.emit('file:visibility:changed', data);
|
|
console.log('File visibility changed:', data.id, data.isVisible);
|
|
});
|
|
|
|
socket.on('disconnect', () => {
|
|
userCount--;
|
|
io.emit('user:count', userCount);
|
|
console.log(`User disconnected. Total users: ${userCount}`);
|
|
});
|
|
});
|
|
|
|
app.prepare().then(() => {
|
|
// Start Next.js server
|
|
createServer(async (req, res) => {
|
|
try {
|
|
const parsedUrl = parse(req.url, true);
|
|
await handler(req, res, parsedUrl);
|
|
} catch (err) {
|
|
console.error('Error occurred handling', req.url, err);
|
|
res.statusCode = 500;
|
|
res.end('internal server error');
|
|
}
|
|
})
|
|
.once('error', (err) => {
|
|
console.error(err);
|
|
process.exit(1);
|
|
})
|
|
.listen(port, () => {
|
|
console.log(`> Ready on http://${hostname}:${port}`);
|
|
});
|
|
|
|
// Start Socket.IO server
|
|
httpServer.listen(socketPort, () => {
|
|
console.log(`> Socket.IO server ready on http://${hostname}:${socketPort}`);
|
|
});
|
|
}); |