开发环境

thinkphp 8.0
php 8.2 创建项目:composer create-project topthink/think chatphp
安装composer require workerman/workerman
composer require topthink/think-worker:* -W

注意将composer.json进行以下修改:

{
    "name": "topthink/think",
    "description": "the new thinkphp framework",
    "type": "project",
    "keywords": [
        "framework",
        "thinkphp",
        "ORM"
    ],
    "homepage": "https://www.thinkphp.cn/",
    "license": "Apache-2.0",
    "authors": [
        {
            "name": "liu21st",
            "email": "liu21st@gmail.com"
        },
        {
            "name": "yunwuxin",
            "email": "448901948@qq.com"
        }
    ],
    "require": {
        "php": ">=7.2.5",
        "topthink/framework": "^6.1.0",
        "topthink/think-orm": "^2.0",
        "topthink/think-filesystem": "^1.0",
        "workerman/workerman": "^3.5",
        "topthink/think-worker": "*"
    },
    "require-dev": {
        "symfony/var-dumper": "^4.2",
        "topthink/think-trace": "^1.0"
    },
    "autoload": {
        "psr-4": {
            "app\\": "app"
        },
        "psr-0": {
            "": "extend/"
        }
    },
    "config": {
        "preferred-install": "dist"
    },
    "scripts": {
        "post-autoload-dump": [
            "@php think service:discover",
            "@php think vendor:publish"
        ]
    }
}

composer update 进行升级

在app 中controller 创建Chat.php

端口号为 2346

<?php
namespace app\controller;

use Workerman\Worker;
use think\worker\Server;

class Chat extends Server
{
    protected $socket = 'websocket://0.0.0.0:2346';
    
    protected $groups = [];       // 存储用户与群组的映射
    protected $kickedUsers = [];  // 存储被踢出用户的信息
    protected $groupUsers = [];   // 存储每个群组中的用户列表

    public function onMessage($connection, $data)
    {
        $data = json_decode($data, true);

        switch ($data['type']) {
            case 'joinGroup':
                $this->joinGroup($connection, $data);
                break;
            case 'sendMessage':
                $this->sendMessage($connection, $data);
                break;
            case 'kickUser':
                $this->kickUser($data);
                break;
            default:
                break;
        }
    }

    public function onConnect($connection)
    {
        echo "New connection: {$connection->id}\n";
    }

    public function onClose($connection)
    {
        if (isset($this->groups[$connection->id])) {
            $groupName = $this->groups[$connection->id]['groupName'];
            $userName = $this->groups[$connection->id]['userName'];

            $this->groupUsers[$groupName] = array_filter($this->groupUsers[$groupName], function ($user) use ($userName) {
                return $user !== $userName;
            });

            foreach ($this->worker->connections as $client) {
                $client->send(json_encode([
                    'type' => 'userList',
                    'users' => $this->groupUsers[$groupName]
                ]));
                $client->send(json_encode(['type' => 'left', 'content' => "$userName 已离开群组 $groupName"]));
            }

            unset($this->groups[$connection->id]);
        }

        echo "Connection {$connection->id} has disconnected\n";
    }

    protected function joinGroup($connection, $data)
    {
        $groupName = $data['groupName'];
        $userName = $data['userName'];

        if (!isset($this->kickedUsers[$groupName]) || !in_array($userName, $this->kickedUsers[$groupName])) {
            $this->groups[$connection->id] = ['groupName' => $groupName, 'userName' => $userName];
            $this->groupUsers[$groupName][] = $userName;

            foreach ($this->worker->connections as $client) {
                $client->send(json_encode([
                    'type' => 'userList',
                    'users' => $this->groupUsers[$groupName]
                ]));
                $client->send(json_encode(['type' => 'join', 'content' => "$userName 加入"]));
            }

            echo "$userName has joined the group $groupName\n";
        } else {
            $connection->send(json_encode(['type' => 'kick', 'content' => "$userName 被踢"]));
        }
    }

    protected function sendMessage($connection, $data)
    {
        $groupName = $data['group_name'];
        $userName = $data['user_name'];

        if (!isset($this->kickedUsers[$groupName]) || !in_array($userName, $this->kickedUsers[$groupName])) {
            foreach ($this->worker->connections as $client) {
                if (isset($this->groups[$client->id]) && $this->groups[$client->id]['groupName'] === $groupName) {
                    $client->send(json_encode($data));
                }
            }

            echo "$userName sent a message to $groupName\n";
        } else {
            $connection->send(json_encode(['type' => 'kick', 'content' => "$userName 被踢"]));
        }
    }

    protected function kickUser($data)
    {
        $groupName = $data['groupName'];
        $userName = $data['userName'];

        foreach ($this->worker->connections as $client) {
            if (isset($this->groups[$client->id]) && $this->groups[$client->id]['groupName'] === $groupName && $this->groups[$client->id]['userName'] === $userName) {
                $client->send(json_encode(['type' => 'kick', 'content' => "$userName 被踢"]));
                $client->close();

                $this->groupUsers[$groupName] = array_filter($this->groupUsers[$groupName], function ($user) use ($userName) {
                    return $user !== $userName;
                });

                foreach ($this->worker->connections as $otherClient) {
                    $otherClient->send(json_encode([
                        'type' => 'userList',
                        'users' => $this->groupUsers[$groupName]
                    ]));
                }

                $this->kickedUsers[$groupName][] = $userName;
                break;
            }
        }

        echo "$userName 被踢出群组 $groupName\n";
    }
}


点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部