php实现在线客服插件
实现基础功能
使用PHP结合WebSocket技术建立实时通信。安装Ratchet库(PHP WebSocket库),通过Composer进行安装:
composer require cboden/ratchet
创建WebSocket服务器脚本(例如server.php),处理连接、消息收发和断开事件:
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
$this->clients->attach($conn);
}
public function onMessage(ConnectionInterface $from, $msg) {
foreach ($this->clients as $client) {
$client->send($msg);
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e) {
$conn->close();
}
}
$app = new Ratchet\App('localhost', 8080);
$app->route('/chat', new Chat, array('*'));
$app->run();
前端交互界面
创建HTML页面引入JavaScript WebSocket客户端,实现消息发送和接收功能:
<div id="chat-box" style="height:300px;overflow-y:scroll;"></div>
<input type="text" id="message" placeholder="输入消息">
<button onclick="sendMessage()">发送</button>
<script>
const conn = new WebSocket('ws://localhost:8080/chat');
conn.onmessage = function(e) {
document.getElementById('chat-box').innerHTML +=
'<div>' + e.data + '</div>';
};
function sendMessage() {
const msg = document.getElementById('message').value;
conn.send(msg);
document.getElementById('message').value = '';
}
</script>
用户身份识别
在连接建立时传递用户身份信息,服务器端进行区分存储。修改前端连接代码:
const userId = 'user_' + Math.random().toString(36).substr(2,9);
const conn = new WebSocket('ws://localhost:8080/chat?userId=' + userId);
服务器端解析查询参数并存储用户信息:
public function onOpen(ConnectionInterface $conn) {
parse_str($conn->httpRequest->getUri()->getQuery(), $query);
$conn->userId = $query['userId'];
$this->clients->attach($conn);
}
消息持久化存储
创建MySQL表存储聊天记录:

CREATE TABLE chat_messages (
id INT AUTO_INCREMENT PRIMARY KEY,
sender_id VARCHAR(50),
message TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
在消息处理时插入数据库记录:
public function onMessage(ConnectionInterface $from, $msg) {
// 存储到数据库
$pdo = new PDO('mysql:host=localhost;dbname=chat_db', 'username', 'password');
$stmt = $pdo->prepare("INSERT INTO chat_messages (sender_id, message) VALUES (?, ?)");
$stmt->execute([$from->userId, $msg]);
// 广播消息
foreach ($this->clients as $client) {
$client->send(json_encode([
'user' => $from->userId,
'message' => $msg
]));
}
}
客服人员分配
实现简单的轮询分配策略,创建客服在线列表:
class Chat implements MessageComponentInterface {
protected $clients;
protected $supportStaff = [];
public function onOpen(ConnectionInterface $conn) {
parse_str($conn->httpRequest->getUri()->getQuery(), $query);
$conn->userId = $query['userId'];
$conn->role = $query['role'] ?? 'customer';
if ($conn->role === 'support') {
$this->supportStaff[] = $conn;
} else {
$this->clients->attach($conn);
}
}
}
历史消息加载
添加API端点返回历史消息:

// 创建HTTP端点
$app->get('/history', function(Request $request) {
$pdo = new PDO('mysql:host=localhost;dbname=chat_db', 'username', 'password');
$stmt = $pdo->query("SELECT * FROM chat_messages ORDER BY created_at DESC LIMIT 50");
return new Response(json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)));
});
前端加载历史记录:
fetch('/history')
.then(res => res.json())
.then(messages => {
messages.reverse().forEach(msg => {
document.getElementById('chat-box').innerHTML +=
`<div><strong>${msg.sender_id}:</strong> ${msg.message}</div>`;
});
});
运行与部署
启动WebSocket服务器:
php server.php
配置Nginx反向代理WebSocket连接:
location /chat {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
使用Supervisor保持进程常驻:
[program:chat_server]
command=php /path/to/server.php
autostart=true
autorestart=true
stderr_logfile=/var/log/chat_server.err.log
stdout_logfile=/var/log/chat_server.out.log






