第九章:Node.js应用场景实战
9.1 Web服务器应用
// web-server.js
/**
* Web服务器应用
* 功能:提供用户管理的RESTful API
*/
const express = require('express');
const app = express();
const PORT = 3000;
app.use(express.json());
// 内存数据存储
const users = [];
let nextId = 1;
// 获取所有用户
app.get('/api/users', (req, res) => {
res.json({ data: users });
});
// 获取单个用户
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) {
return res.status(404).json({ error: '用户不存在' });
}
res.json({ data: user });
});
// 创建用户
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
const user = {
id: nextId++,
name,
email,
createdAt: new Date()
};
users.push(user);
res.status(201).json({ data: user });
});
// 更新用户
app.put('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) {
return res.status(404).json({ error: '用户不存在' });
}
Object.assign(user, req.body);
res.json({ data: user });
});
// 删除用户
app.delete('/api/users/:id', (req, res) => {
const index = users.findIndex(u => u.id === parseInt(req.params.id));
if (index === -1) {
return res.status(404).json({ error: '用户不存在' });
}
users.splice(index, 1);
res.json({ message: '删除成功' });
});
app.listen(PORT, () => {
console.log(`服务器运行在 http://localhost:${PORT}`);
});
9.2 实时聊天应用
// chat-server.js
/**
* 实时聊天服务器
* 功能:多人在线聊天室
* 技术:Socket.io
*/
const express = require('express');
const { createServer } = require('http');
const { Server } = require('socket.io');
const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer, {
cors: { origin: '*' }
});
// 存储在线用户
const onlineUsers = new Map();
io.on('connection', (socket) => {
console.log('用户连接:', socket.id);
// 用户加入
socket.on('join', (username) => {
onlineUsers.set(socket.id, {
id: socket.id,
username,
joinTime: new Date()
});
socket.broadcast.emit('userJoined', {
username,
message: `${username} 加入了聊天室`,
onlineCount: onlineUsers.size
});
socket.emit('onlineUsers', Array.from(onlineUsers.values()));
});
// 接收消息
socket.on('message', (data) => {
const user = onlineUsers.get(socket.id);
if (!user) return;
const message = {
id: Date.now(),
username: user.username,
content: data.content,
timestamp: new Date()
};
io.emit('message', message);
});
// 用户断开
socket.on('disconnect', () => {
const user = onlineUsers.get(socket.id);
if (user) {
onlineUsers.delete(socket.id);
socket.broadcast.emit('userLeft', {
username: user.username,
message: `${user.username} 离开了聊天室`,
onlineCount: onlineUsers.size
});
}
});
});
httpServer.listen(3000, () => {
console.log('聊天服务器运行中');
});
9.3 命令行工具
// cli-tool.js
#!/usr/bin/env node
/**
* 文件批量重命名工具
* 用法: node cli-tool.js <目录> <模式>
*/
const fs = require('fs').promises;
const path = require('path');
async function renameFiles(dir, pattern) {
const files = await fs.readdir(dir);
let counter = 1;
for (const file of files) {
const oldPath = path.join(dir, file);
const stat = await fs.stat(oldPath);
if (stat.isFile()) {
const ext = path.extname(file);
const newName = pattern.replace('*', String(counter).padStart(3, '0')) + ext;
const newPath = path.join(dir, newName);
await fs.rename(oldPath, newPath);
console.log(`${file} -> ${newName}`);
counter++;
}
}
}
const [dir, pattern] = process.argv.slice(2);
if (!dir || !pattern) {
console.log('用法: node cli-tool.js <目录> <模式>');
process.exit(1);
}
renameFiles(dir, pattern).catch(console.error);
9.4 网络爬虫
// crawler.js
/**
* 网页爬虫
* 功能:抓取网页内容并提取数据
*/
const https = require('https');
const cheerio = require('cheerio');
// 发送HTTP请求
function fetch(url) {
return new Promise((resolve, reject) => {
https.get(url, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => resolve(data));
}).on('error', reject);
});
}
// 解析HTML并提取数据
async function crawl(url) {
try {
const html = await fetch(url);
const $ = cheerio.load(html);
const data = {
title: $('title').text(),
links: $('a').map((i, el) => $(el).attr('href')).get(),
images: $('img').map((i, el) => $(el).attr('src')).get()
};
console.log('抓取结果:', data);
return data;
} catch (err) {
console.error('抓取失败:', err);
}
}
// 使用
crawl('https://example.com');
9.5 定时任务
// scheduler.js
/**
* 定时任务调度器
* 功能:定时执行特定任务
*/
const schedule = require('node-schedule');
// 每天凌晨执行
schedule.scheduleJob('0 0 * * *', () => {
console.log('执行每日任务:', new Date());
// 数据备份、清理等操作
});
// 每分钟执行
schedule.scheduleJob('*/1 * * * *', () => {
console.log('执行分钟任务:', new Date());
});
// 特定时间执行
const date = new Date(2024, 0, 1, 0, 0, 0);
schedule.scheduleJob(date, () => {
console.log('新年快乐!');
});
console.log('定时任务已启动');
9.6 文件处理服务
// file-service.js
/**
* 文件上传处理服务
* 功能:处理文件上传、压缩、转换
*/
const express = require('express');
const multer = require('multer');
const fs = require('fs').promises;
const path = require('path');
const sharp = require('sharp');
const app = express();
const upload = multer({ dest: 'uploads/' });
// 上传图片并生成缩略图
app.post('/upload', upload.single('image'), async (req, res) => {
try {
const inputPath = req.file.path;
const outputDir = 'thumbnails/';
// 确保目录存在
await fs.mkdir(outputDir, { recursive: true });
// 生成缩略图
const thumbnailPath = path.join(outputDir, `thumb_${req.file.filename}.jpg`);
await sharp(inputPath)
.resize(200, 200)
.toFile(thumbnailPath);
res.json({
original: inputPath,
thumbnail: thumbnailPath
});
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.listen(3000);