swoole端
<?php
// 创建一个WebSocket服务器
$ws = new Swoole\WebSocket\Server("0.0.0.0", 9501);
// 创建一个Swoole Table实例,用于存储消息队列
$table = new Swoole\Table(1024); // 设置表容量
$table->column('topic', Swoole\Table::TYPE_STRING, 64); // 主题
$table->column('message', Swoole\Table::TYPE_STRING, 255); // 消息
$table->create();
// 监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
echo "Client {$request->fd} connected.\n";
});
// 监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) use ($table) {
// 解析客户端发送的消息
$data = json_decode($frame->data, true);
// 检查是否为发布消息操作
if (isset($data['action']) && $data['action'] === 'publish') {
// 存储消息到Table
$key = uniqid(); // 生成唯一键
$table->set($key, ['topic' => $data['topic'], 'message' => $data['message']]);
// 广播消息给所有已订阅此主题的客户端
broadcastMessage($ws, $data['topic']);
}
});
// 监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
echo "Client {$fd} disconnected.\n";
});
// 启动服务器
$ws->start();
// 广播消息给已订阅特定主题的客户端
function broadcastMessage(Swoole\WebSocket\Server $ws, $topic) {
global $table;
// 遍历所有连接的客户端
foreach ($ws->connections as $fd) {
// 获取客户端发送的订阅主题
$clientTopic = $ws->exist($fd) ? $ws->connection_info($fd)['topic'] : null;
// 如果客户端订阅了该主题,则广播消息
if ($clientTopic === $topic) {
// 遍历存储的消息,找到匹配主题的消息并发送
$table->rewind();
while ($row = $table->current()) {
if ($row['topic'] === $topic) {
$ws->push($fd, json_encode(['topic' => $topic, 'message' => $row['message']]));
}
$table->next();
}
}
}
}html端js连接websocket示例代码<script>
var ws = new WebSocket("ws://localhost:9501");
ws.onopen = function() {
console.log("Connected to server");
ws.send(JSON.stringify({action: 'subscribe', topic: 'myTopic'}));
};
ws.onmessage = function(event) {
var data = JSON.parse(event.data);
console.log("Received message:", data.topic, data.message);
};
</script> 网友回复


