+
95
-

回答

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>

网友回复

我知道答案,我要回答