无Redis实时客服系统实现文档
无Redis实时客服系统实现文档
📋 项目概述
本项目实现了一个基于 Node.js + MongoDB 的实时客服系统,无需 Redis,通过 Socket.IO 实现实时通信,使用 MongoDB 进行数据持久化。
🏗️ 系统架构
核心组件
-
后端框架: Fastify (Node.js)
-
数据库: MongoDB
-
实时通信: Socket.IO
-
前端框架: Handlebars + Tailwind CSS
-
认证: Cookie-based 认证
架构特点
-
无Redis依赖: 使用内存 Map 管理在线状态
-
实时通信: WebSocket 双向通信
-
数据持久化: MongoDB 存储聊天记录
-
响应式设计: 现代化 UI 界面
📊 数据库设计
1. 客服表 (web_chat_agent)
{
_id: ObjectId,
username: String, // 用户名
password: String, // 加密密码
realName: String, // 真实姓名
email: String, // 邮箱
phone: String, // 电话
skills: Array, // 技能标签
maxConcurrent: Number, // 最大并发数
status: String, // 状态: ONLINE/OFFLINE
isActive: Boolean, // 是否启用
add_time: Number // 创建时间
}
2. 聊天房间表 (web_chat_room)
{
_id: ObjectId,
customerId: String, // 客户ID
customerName: String, // 客户姓名
agentId: ObjectId, // 客服ID (可选)
status: String, // 状态: WAITING/SERVING/CLOSED
category: String, // 咨询类别
priority: String, // 优先级: LOW/MEDIUM/HIGH
createdAt: Number, // 创建时间
endedAt: Number, // 结束时间 (可选)
endReason: String // 结束原因 (可选)
}
3. 聊天消息表 (web_chat_message)
{
_id: ObjectId,
roomId: ObjectId, // 房间ID
senderId: String, // 发送者ID
senderType: String, // 发送者类型: CUSTOMER/AGENT
content: String, // 消息内容
msgType: String, // 消息类型: text
createdAt: Number, // 发送时间
isSystem: Boolean // 是否系统消息
}
4. 客服统计表 (web_chat_agent_stats)
{
_id: ObjectId,
agentId: ObjectId, // 客服ID
date: String, // 统计日期
totalSessions: Number, // 总会话数
avgResponseTime: Number, // 平均响应时间
customerSatisfaction: Number // 客户满意度
}
🔧 核心实现
1. Socket.IO 管理器 (socketManager.ts)
内存状态管理
// 客服在线状态管理
const onlineAgents = new Map<string, {
socketId: string;
lastPing: number;
currentRooms: string[];
}>();
// 房间连接管理
const roomConnections = new Map<string, {
customerSocketId?: string;
agentSocketId?: string;
}>();
主要事件处理
-
agent:login- 客服登录 -
customer:join- 客户加入房间 -
agent:join- 客服加入房间 -
agent:leave- 客服离开房间 -
msg:send- 发送消息 -
disconnect- 断开连接
2. 房间分配策略
原子操作分配
const result = await collection('web_chat_room').findOneAndUpdate(
{
_id: new ObjectId(roomId),
status: 'WAITING'
},
{
$set: {
status: 'SERVING',
agentId: new ObjectId(agentId)
}
},
{ returnDocument: 'after' }
);
实时通知机制
// 通知客户房间已分配
socketManager.notifyRoomAssigned(roomId, agentId);
// 通知所有客服有新房间
socketManager.notifyNewRoom(room);
3. 消息处理流程
消息发送
-
客户端发送
msg:send事件 -
服务器保存到 MongoDB
-
广播
msg:new事件给房间内所有用户
消息持久化
const message = {
roomId: new ObjectId(data.roomId),
senderId: data.senderId,
senderType: data.senderType,
content: data.content,
msgType: 'text',
createdAt: Date.now(),
isSystem: false
};
await collection('web_chat_message').insertOne(message);
🎨 前端实现
1. 客户聊天页面 (customer_chat.hbs)
核心功能
-
自动重连: 页面刷新后自动恢复会话
-
实时消息: WebSocket 实时接收消息
-
状态管理: 显示连接状态和聊天状态
-
消息样式: 客户消息右对齐蓝色,客服消息左对齐绿色
关键代码
// 自动恢复会话
window.addEventListener('load', () => {
const savedRoomId = localStorage.getItem('customerRoomId');
if (savedRoomId) {
checkRoomStatus();
}
});
// 实时消息接收
socket.on('msg:new', (message) => {
if (message.senderType === 'AGENT') {
addMessage('客服', message.content);
} else if (message.senderType === 'CUSTOMER') {
addMessage('我', message.content);
}
});
2. 客服工作台 (agent_dashboard.hbs)
核心功能
-
多房间管理: 支持同时服务多个房间
-
房间切换: 可以在不同房间间切换
-
历史会话: 查看已结束的聊天记录
-
实时通知: 新房间到达时实时提醒
关键代码
// 房间切换机制
async function switchToRoom(roomId) {
// 离开当前房间
if (currentRoomId && socket) {
socket.emit('agent:leave', { roomId: currentRoomId, agentId: String(agentId) });
}
// 加入新房间
socket.emit('agent:join', { roomId: roomId, agentId: String(agentId) });
// 加载历史消息
await loadRoomHistory(roomId);
}
// 实时新房间通知
socket.on('room:new', (room) => {
addWaitingRoom(room);
});
🚀 部署和运行
1. 环境要求
-
Node.js >= 16
-
MongoDB >= 4.4
-
pnpm (推荐) 或 npm
2. 安装依赖
pnpm install
3. 启动开发服务器
pnpm run dev
4. 构建生产版本
pnpm run build
pnpm start
📱 访问路径
客户端
- 客户聊天:
http://localhost:3000/customer-chat
客服端
-
客服登录:
http://localhost:3000/agent/login -
客服注册:
http://localhost:3000/agent/register -
客服工作台:
http://localhost:3000/agent/dashboard
🔄 工作流程
1. 客户发起聊天
-
客户访问
/customer-chat -
点击"开始聊天"按钮
-
系统创建聊天房间 (状态: WAITING)
-
客户进入等待状态
2. 客服接受聊天
-
客服登录工作台
-
在"等待中的房间"看到新房间
-
点击接受房间
-
系统分配房间给客服 (状态: SERVING)
-
客户收到通知,开始聊天
3. 实时聊天
-
双方通过 WebSocket 实时发送消息
-
消息保存到 MongoDB
-
支持表情、文本等消息类型
4. 结束聊天
-
客服点击"结束聊天"
-
系统更新房间状态 (状态: CLOSED)
-
聊天记录保存到历史会话
-
双方收到结束通知
🎯 技术亮点
1. 无Redis架构
-
使用内存 Map 管理在线状态
-
减少系统复杂度
-
降低部署成本
2. 原子操作
-
使用 MongoDB
findOneAndUpdate确保房间分配的唯一性 -
避免并发问题
3. 实时通信
-
Socket.IO 提供可靠的 WebSocket 连接
-
自动重连机制
-
房间级别的消息广播
4. 用户体验
-
响应式设计
-
现代化 UI
-
流畅的动画效果
5. 数据持久化
-
完整的聊天记录保存
-
历史会话查询
-
客服统计功能
🔧 扩展功能
1. 可扩展的功能
-
文件上传
-
语音消息
-
视频通话
-
客服评价系统
-
智能分配算法
-
多语言支持
2. 性能优化
-
消息分页加载
-
图片压缩
-
连接池优化
-
缓存策略
📝 总结
本系统成功实现了无Redis的实时客服系统,通过 Socket.IO 和 MongoDB 的组合,提供了完整的实时聊天功能。系统具有良好的扩展性和可维护性,可以作为企业级客服系统的基础框架。
核心优势:
-
✅ 无需 Redis,降低部署复杂度
-
✅ 实时通信,用户体验良好
-
✅ 数据持久化,完整记录保存
-
✅ 现代化 UI,界面美观
-
✅ 代码清晰,易于维护和扩展
本文由萧兮的博客原创发布,欢迎转载,转载务必保留原文链接。
萧兮的博客:https://www.20010515.xyz · 原文:https://www.20010515.xyz/posts/a6445dad-9c1e-469b-990d-5ecb868a92e6