Workerman 和 Swoole 都可以实现 1v1 聊天和群聊功能。以下是两者的基本实现思路和示例代码。
1. Workerman 实现
1v1 聊天
- 客户端连接:用户连接到 Workerman 服务器,服务器为每个连接分配一个唯一的 ID。
- 消息发送:用户发送消息时,服务器根据目标用户的 ID 将消息发送给对应的连接。
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
// 创建一个 Worker 进程
$worker = new Worker("websocket://0.0.0.0:2346");
$connections = []; // 存储所有连接
$worker->onConnect = function($connection) use (&$connections) {
$connections[$connection->id] = $connection; // 保存连接
};
$worker->onMessage = function($connection, $data) use (&$connections) {
$message = json_decode($data, true);
$targetId = $message['target_id']; // 获取目标 ID
$text = $message['text'];
// 发送消息给目标用户
if (isset($connections[$targetId])) {
$connections[$targetId]->send(json_encode(['from' => $connection->id, 'text' => $text]));
}
};
$worker->onClose = function($connection) use (&$connections) {
unset($connections[$connection->id]); // 移除连接
};
Worker::runAll();
群聊
- 群组管理:可以创建群组,并将用户加入群组,维护群组成员列表。
- 消息广播:当用户向群组发送消息时,将消息广播给群组中的所有成员。
$groups = []; // 存储群组信息
$worker->onMessage = function($connection, $data) use (&$connections, &$groups) {
$message = json_decode($data, true);
$groupId = $message['group_id']; // 获取群组 ID
$text = $message['text'];
// 广播消息给群组内所有成员
if (isset($groups[$groupId])) {
foreach ($groups[$groupId] as $memberId) {
if (isset($connections[$memberId])) {
$connections[$memberId]->send(json_encode(['from' => $connection->id, 'text' => $text]));
}
}
}
};
2. Swoole 实现
1v1 聊天
- 连接管理:使用 Swoole 的 Table 或数组来管理用户连接。
- 消息转发:通过用户 ID 找到对应的连接并转发消息。
use Swoole\WebSocket\Server;
$server = new Server("0.0.0.0", 9501);
$connections = []; // 存储连接
$server->on('open', function ($server, $request) use (&$connections) {
$connections[$request->fd] = $request->fd; // 保存连接
});
$server->on('message', function ($server, $frame) use (&$connections) {
$message = json_decode($frame->data, true);
$targetId = $message['target_id']; // 目标用户 ID
$text = $message['text'];
// 发送消息给目标用户
if (isset($connections[$targetId])) {
$server->push($targetId, json_encode(['from' => $frame->fd, 'text' => $text]));
}
});
$server->on('close', function ($server, $fd) use (&$connections) {
unset($connections[$fd]); // 移除连接
});
$server->start();
群聊
- 群组管理:维护每个群组的成员列表,可以使用 Swoole 的 Table。
- 消息广播:当接收到群组消息时,将消息广播给群组的所有成员。
$groups = []; // 存储群组信息
$server->on('message', function ($server, $frame) use (&$connections, &$groups) {
$message = json_decode($frame->data, true);
$groupId = $message['group_id']; // 群组 ID
$text = $message['text'];
// 广播消息给群组内所有成员
if (isset($groups[$groupId])) {
foreach ($groups[$groupId] as $memberId) {
if (isset($connections[$memberId])) {
$server->push($memberId, json_encode(['from' => $frame->fd, 'text' => $text]));
}
}
}
});
总结
- 连接管理:在两者中,都需要管理用户连接,可以使用数组或数据库。
- 消息处理:1v1 聊天通过目标用户 ID 精确发送消息;群聊则通过群组 ID 广播消息。
- 持久连接:WebSocket 协议允许持久连接,实现实时通信。
通过以上代码示例和思路,可以实现基础的 1v1 聊天和群聊功能。具体实现可以根据需求进行扩展和优化。