ThinkPHP6+WebSocket实现实时聊天系统全栈开发指南
一、系统架构设计
本系统采用前后端分离架构:
- 后端服务:ThinkPHP6 + Swoole WebSocket
- 前端界面:Vue.js + WebSocket客户端
- 数据存储:MySQL + Redis
- 消息协议:自定义JSON格式
二、环境准备与配置
1. 安装Swoole扩展
pecl install swoole
在php.ini中添加:
extension=swoole.so
2. 创建ThinkPHP6项目
composer create-project topthink/think tp6-chat
cd tp6-chat
composer require topthink/think-swoole
三、WebSocket服务实现
1. 创建WebSocket服务类
app/service/WebSocketService.php:
<?php
namespace appservice;
use SwooleWebSocketServer;
use thinkfacadeCache;
class WebSocketService
{
private $server;
private $config = [
'host' => '0.0.0.0',
'port' => 9502,
'options' => [
'worker_num' => 4,
'daemonize' => false,
'max_request' => 1000
]
];
public function __construct()
{
$this->server = new Server(
$this->config['host'],
$this->config['port']
);
$this->server->set($this->config['options']);
}
public function start()
{
$this->server->on('open', function (Server $server, $request) {
$userId = $request->get['uid'];
Cache::set('ws_user_' . $userId, $request->fd);
});
$this->server->on('message', function (Server $server, $frame) {
$data = json_decode($frame->data, true);
$this->handleMessage($data);
});
$this->server->on('close', function (Server $server, $fd) {
Cache::delete('ws_fd_' . $fd);
});
$this->server->start();
}
private function handleMessage($data)
{
switch ($data['type']) {
case 'private':
$this->sendPrivateMessage($data);
break;
case 'group':
$this->sendGroupMessage($data);
break;
}
}
private function sendPrivateMessage($data)
{
$toFd = Cache::get('ws_user_' . $data['to']);
if ($toFd) {
$this->server->push($toFd, json_encode([
'type' => 'message',
'from' => $data['from'],
'content' => $data['content'],
'time' => date('Y-m-d H:i:s')
]));
}
}
}
四、业务逻辑整合
1. 用户认证中间件
app/middleware/Auth.php:
<?php
namespace appmiddleware;
use appserviceJwtService;
class Auth
{
public function handle($request, Closure $next)
{
$token = $request->header('Authorization');
if (!$payload = JwtService::verify($token)) {
return json(['code' => 401, 'msg' => '认证失败']);
}
$request->user = $payload;
return $next($request);
}
}
2. 消息控制器
app/controller/Message.php:
<?php
namespace appcontroller;
use thinkRequest;
use appmodelMessage as MessageModel;
use appserviceWebSocketClient;
class Message
{
public function send(Request $request)
{
$data = $request->post();
$message = MessageModel::create([
'from_id' => $request->user->id,
'to_id' => $data['to_id'],
'content' => $data['content'],
'type' => $data['type']
]);
WebSocketClient::send([
'type' => 'private',
'from' => $request->user->id,
'to' => $data['to_id'],
'content' => $data['content']
]);
return json(['code' => 200, 'data' => $message]);
}
}
五、前端实现关键代码
1. WebSocket客户端连接
const socket = new WebSocket(`ws://${location.hostname}:9502?uid=${userId}`);
socket.onmessage = function(event) {
const data = JSON.parse(event.data);
switch(data.type) {
case 'message':
addMessageToChat(data);
break;
case 'notification':
showNotification(data);
break;
}
};
function sendMessage(content, toId) {
socket.send(JSON.stringify({
type: 'private',
from: currentUser.id,
to: toId,
content: content
}));
}
六、系统优化与扩展
- 心跳检测:防止连接意外断开
- 消息队列:使用Redis处理高并发消息
- 消息持久化:异步存储聊天记录
- 分布式部署:多节点WebSocket服务
- 消息加密:保障通信安全