'# 基于node.js的居家养老服务系统
一、背景与问题
居家养老服务系统是面向老年人的智慧养老解决方案,核心需求包括:
- 服务人员管理(注册/排班/考勤)
- 服务预约与调度
- 健康数据监测(可选)
- 家庭成员互动
- 应急响应机制
传统方案常采用Java/PHP开发,但存在以下痛点:
- 高并发场景下性能不足
- 实时通知功能实现复杂
- 跨平台服务能力不足
- 微服务架构部署成本高
Node.js的非阻塞I/O模型和事件驱动特性,使其在处理实时通信、并发请求、服务调度等场景时具有天然优势。本文将深入探讨基于Node.js的居家养老系统实现方案。
二、基本原理
1. 架构设计原则
采用分层架构:
[客户端] -> [API网关] -> [业务层] -> [数据层] -> [存储层]
核心组件:
- 服务注册中心(基于Redis)
- 任务调度引擎(基于Quartz)
- 实时通信(基于WebSocket)
- 数据持久化(MongoDB/MySQL)
2. 技术选型依据
| 模块 | 技术 | 选型理由 |
|---|
| 实时通信 | WebSocket | 低延迟,适合服务通知 |
| 任务调度 | Node-schedule | 轻量级,支持cron表达式 |
| 数据库 | MongoDB | 灵活文档模型,适合用户画像 |
| 安全 | JWT | 无状态认证,适合分布式架构 |
三、环境准备
# 安装依赖
npm init -y
npm install express mongoose socket.io bcryptjs jsonwebtoken
{
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
}
}
四、核心实现
1. 实时通信模块
// socket.js
const { createServer } = require('http');
const { Server } = require('socket.io');
const httpServer = createServer((req, res) => {
res.writeHead(200);
res.end('WebSocket Server');
});
const io = new Server(httpServer, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"]
}
});
io.on('connection', (socket) => {
console.log('Client connected');
socket.on('service_request', (data) => {
io.emit('service_notification', data);
});
socket.on('disconnect', () => {
console.log('Client disconnected');
});
});
httpServer.listen(3001, () => {
console.log('WebSocket server running on port 3001');
});
关键点解释:
- 使用HTTP Server承载WebSocket连接
- 设置CORS策略保证前端访问安全
- 通过
io.emit实现广播通知 - 使用
socket.on处理客户端事件
2. 服务预约接口
// routes/api.js
const express = require('express');
const router = express.Router();
const { Service } = require('../models');
router.post('/services', async (req, res) => {
try {
const { type, time, location, user } = req.body;
// 验证预约时间有效性
const now = new Date();
const appointmentTime = new Date(time);
if (appointmentTime < now) {
return res.status(400).json({ error: '预约时间不能早于当前时间' });
}
// 创建服务记录
const service = await Service.create({
type,
time: appointmentTime,
location,
user,
status: 'pending'
});
res.status(201).json(service);
} catch (err) {
console.error(err);
res.status(500).json({ error: '服务器内部错误' });
}
});
关键点解释:
- 使用async/await处理异步操作
- 严格校验预约时间有效性
- 使用Mongoose进行数据持久化
- 增加错误处理机制
3. 任务调度系统
// scheduler.js
const schedule = require('node-schedule');
const { Service } = require('./models');
// 每小时检查待处理预约
schedule.scheduleJob('* * * * *', async () => {
const pendingServices = await Service.find({ status: 'pending' });
for (const service of pendingServices) {
// 检查是否超时
const now = new Date();
const timeDiff = (now - new Date(service.time)) / 1000;
if (timeDiff > 3600) { // 超过1小时
await Service.findByIdAndUpdate(service._id, { status: 'expired' });
} else {
// 发送通知
io.emit('service_notification', {
message: `您有新的服务预约,请注意查看位置信息`,
serviceId: service._id
});
}
}
});
关键点解释:
- 使用node-schedule实现定时任务
- 设置合理的超时阈值(1小时)
- 通过WebSocket发送通知
- 使用MongoDB的findAndUpdate原子操作
五、完整案例
1. 项目结构
/homecare-system/
├── models/ # 数据模型
│ └── Service.js
├── routes/ # 路由
│ └── api.js
├── controllers/ # 业务逻辑
│ └── service.js
├── services/ # 服务层
│ └── scheduler.js
├── config/ # 配置文件
│ └── db.js
├── utils/ # 工具函数
│ └── auth.js
├── app.js # 主程序
├── index.js # 入口文件
└── package.json
2. 完整服务模块
// models/Service.js
const mongoose = require('mongoose');
const ServiceSchema = new mongoose.Schema({
type: {
type: String,
enum: ['cleaning', 'medical', 'transport'],
required: true
},
time: {
type: Date,
required: true
},
location: {
type: String,
required: true
},
user: {
type: String,
required: true
},
status: {
type: String,
enum: ['pending', 'confirmed', 'expired'],
default: 'pending'
},
createdAt: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('Service', ServiceSchema);
3. 主程序入口
// index.js
const http = require('http');
const { app } = require('./app');
const { initSocket } = require('./socket');
const server = http.createServer(app);
initSocket(server);
server.listen(3001, () => {
console.log('Homecare system running on port 3001');
});
六、源码解析
1. WebSocket连接管理
// socket.js
const { Server } = require('socket.io');
const io = new Server(httpServer, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"]
}
});
cors配置确保前端应用可以访问后端- 使用
io.emit实现广播通知 - 使用
socket.on处理客户端事件
2. 数据库连接配置
// config/db.js
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/homecare', {
useNewUrlParser: true,
useUnifiedTopology: true
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
db.once('open', () => {
console.log('Connected to MongoDB');
});
关键点:
- 使用连接池优化数据库连接
- 设置
useNewUrlParser和useUnifiedTopology避免过时API - 增加错误处理机制
七、进阶使用
1. 增加身份验证
// utils/auth.js
const jwt = require('jsonwebtoken');
function authenticate(req, res, next) {
const token = req.headers['x-access-token'];
if (!token) {
return res.status(401).json({ error: '缺少认证token' });
}
jwt.verify(token, 'secret_key', (err, decoded) => {
if (err) {
return res.status(401).json({ error: '无效的token' });
}
req.user = decoded;
next();
});
}
2. 增加日志记录
// logger.js
const fs = require('fs');
const path = require('path');
const logDir = path.join(__dirname, 'logs');
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir);
}
const logFile = path.join(logDir, 'service.log');
function log(message) {
fs.appendFile(logFile, `${new Date()}: ${message}\n`, (err) => {
if (err) throw err;
});
}
八、性能与工程实践
1. 性能优化方案
| 优化项 | 方法 | 效果 |
|---|
| 数据库 | 添加索引 | 查询速度提升300% |
| 缓存 | Redis缓存 | 响应时间降低50% |
| 负载 | 集群部署 | 并发处理能力提升4倍 |
2. 异常处理机制
// errorMiddleware.js
function errorHandler(err, req, res, next) {
console.error(err.stack);
if (res.headersSent) {
return next(err);
}
res.status(500).json({
error: '服务器内部错误',
details: err.message
});
}
3. 安全防护措施
- 使用HTTPS加密传输
- 防止SQL注入(使用ORM)
- 防止XSS攻击(过滤用户输入)
- 设置CORS策略
九、常见问题与踩坑
1. 常见错误示例
// 错误示例:未处理异步错误
async function processService() {
const service = await Service.findById(id);
// 未处理可能的错误
service.status = 'confirmed';
await service.save();
}
问题:未处理找不到记录的错误
解决:添加错误处理
async function processService() {
try {
const service = await Service.findById(id);
if (!service) throw new Error('未找到服务记录');
service.status = 'confirmed';
await service.save();
} catch (err) {
console.error(err);
throw err;
}
}
2. 性能陷阱
- 未使用连接池导致数据库连接耗尽
- 未设置超时限制导致阻塞
- 未使用缓存导致重复计算
解决方案:
// 使用连接池
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'homecare',
connectionLimit: 10
});
十、最佳实践
- 使用Mongoose进行数据验证
- 所有接口添加错误处理中间件
- 实时通信使用WebSocket
- 重要操作添加事务支持
- 采用模块化设计,保持代码可维护性
- 定期进行性能测试和压力测试
十一、总结
基于Node.js的居家养老服务系统,通过合理的技术选型和架构设计,能够有效满足高并发、实时通信、服务调度等核心需求。本文深入分析了WebSocket通信、任务调度、数据库操作等关键技术点,提供了完整的代码示例和实践方案。
在实际应用中,该方案特别适合:
- 需要实时通知的养老场景
- 高并发的预约服务系统
- 跨平台的养老服务系统
但需注意:
- 不适合需要复杂事务处理的场景
- 不适合对安全性要求极高的金融系统
- 不适合需要严格ACID特性的业务
通过合理的技术选型和架构设计,Node.js能够为居家养老服务系统提供高效、可靠的解决方案。