基于PHP与Swoole的在线客服系统CRMchat搭建指南

一、系统架构设计思路

在线客服系统的核心需求包括实时通信、会话管理、用户身份识别和历史记录追溯。基于PHP与Swoole的异步非阻塞特性,CRMchat采用分层架构设计:

  1. 连接管理层:Swoole WebSocket服务器负责处理长连接,支持万级并发连接管理。通过onOpenonMessageonClose事件回调实现连接生命周期控制。

  2. 业务逻辑层:PHP实现用户认证、路由分发、消息处理等核心功能。采用MVC模式分离业务逻辑与数据访问,提升代码可维护性。

  3. 数据存储层:MySQL存储用户信息、会话记录等结构化数据,Redis缓存会话状态、在线客服列表等高频访问数据。

  1. // Swoole服务器基础配置示例
  2. $server = new Swoole\WebSocket\Server("0.0.0.0", 9501);
  3. $server->set([
  4. 'worker_num' => 4,
  5. 'heartbeat_check_interval' => 60,
  6. 'heartbeat_idle_time' => 600
  7. ]);

二、环境准备与依赖安装

  1. PHP环境要求

    • PHP 7.4+(推荐8.0+)
    • 安装Swoole扩展(4.5+版本)
    • 启用pcntl、posix扩展(进程管理需要)
  2. 依赖管理工具

    1. composer require predis/predis
    2. composer require monolog/monolog
  3. 数据库初始化

    1. CREATE TABLE `users` (
    2. `id` INT AUTO_INCREMENT PRIMARY KEY,
    3. `username` VARCHAR(50) NOT NULL,
    4. `role` ENUM('customer','agent','admin') DEFAULT 'customer'
    5. );
    6. CREATE TABLE `sessions` (
    7. `id` VARCHAR(32) PRIMARY KEY,
    8. `customer_id` INT NOT NULL,
    9. `agent_id` INT,
    10. `status` ENUM('pending','active','closed') DEFAULT 'pending'
    11. );

三、核心功能实现

1. WebSocket通信实现

通过Swoole的WebSocket协议实现双向通信:

  1. $server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
  2. $data = json_decode($frame->data, true);
  3. switch ($data['type']) {
  4. case 'auth':
  5. handleAuth($server, $frame->fd, $data);
  6. break;
  7. case 'message':
  8. routeMessage($server, $frame->fd, $data);
  9. break;
  10. }
  11. });

2. 用户认证机制

采用JWT令牌实现无状态认证:

  1. function generateToken($userId) {
  2. $payload = [
  3. 'uid' => $userId,
  4. 'exp' => time() + 3600
  5. ];
  6. return JWT::encode($payload, 'your-secret-key');
  7. }
  8. function verifyToken($token) {
  9. try {
  10. $decoded = JWT::decode($token, 'your-secret-key', ['HS256']);
  11. return $decoded->uid;
  12. } catch (Exception $e) {
  13. return false;
  14. }
  15. }

3. 会话路由逻辑

实现智能客服分配算法:

  1. function assignAgent($customerId) {
  2. $redis = new Predis\Client();
  3. $availableAgents = $redis->smembers('available_agents');
  4. if (empty($availableAgents)) {
  5. return false;
  6. }
  7. $agentId = array_shift($availableAgents);
  8. $redis->srem('available_agents', $agentId);
  9. // 创建会话记录
  10. $sessionId = bin2hex(random_bytes(16));
  11. DB::table('sessions')->insert([
  12. 'id' => $sessionId,
  13. 'customer_id' => $customerId,
  14. 'agent_id' => $agentId,
  15. 'status' => 'active'
  16. ]);
  17. return $sessionId;
  18. }

四、性能优化策略

  1. 连接管理优化

    • 设置合理的heartbeat_check_interval(建议60秒)
    • 实现空闲连接自动回收机制
    • 使用连接池管理数据库连接
  2. 消息队列集成

    1. // 使用Redis Stream实现异步消息处理
    2. $redis = new Predis\Client();
    3. $redis->xadd('message_queue', '*', [
    4. 'type' => 'customer_message',
    5. 'content' => $message,
    6. 'session_id' => $sessionId
    7. ]);
  3. 缓存策略设计

    • 热点数据缓存(如在线客服列表)
    • 会话状态缓存(Redis Hash结构)
    • 实施缓存淘汰策略(LRU算法)

五、部署与运维建议

  1. 进程模型配置

    1. $server->set([
    2. 'worker_num' => cpu_count() * 2,
    3. 'task_worker_num' => 4, // 异步任务处理
    4. 'enable_coroutine' => true
    5. ]);
  2. 监控告警体系

    • 连接数监控($server->stats()
    • 内存使用监控
    • 消息处理延迟监控
  3. 水平扩展方案

    • 采用一致性哈希实现多节点部署
    • 共享Redis存储会话状态
    • 实施负载均衡策略

六、完整源码结构说明

  1. /CRMchat
  2. ├── config/ # 配置文件目录
  3. ├── database.php # 数据库配置
  4. └── server.php # Swoole服务器配置
  5. ├── src/
  6. ├── Core/ # 核心类库
  7. ├── Controller/ # 业务控制器
  8. └── Model/ # 数据模型
  9. ├── public/ # Web入口文件
  10. ├── storage/ # 日志与缓存
  11. └── composer.json # 依赖管理

七、常见问题解决方案

  1. 连接断开问题

    • 检查防火墙设置(确保9501端口开放)
    • 调整心跳检测参数
    • 实现断线重连机制
  2. 消息丢失处理

    • 实现消息确认机制
    • 添加消息重试队列
    • 记录消息处理日志
  3. 高并发场景优化

    • 启用Swoole协程(enable_coroutine => true
    • 实施读写分离
    • 使用连接池复用数据库连接

本方案通过PHP与Swoole的深度整合,实现了低延迟、高并发的在线客服系统。实际部署时建议结合企业具体需求调整架构参数,特别是连接数配置和缓存策略。对于超大规模部署场景,可考虑引入消息中间件实现跨节点通信,进一步提升系统可扩展性。