workerman

workerman—官网

workerman_第1张图片

具体的上手体验流程 workerman手册 -> GatewayWorker手册 -> webman手册 -> webman-admin手册

文档关系

刚上手的时候看到四个文档,不知道看哪个,感觉很迷茫。简单介绍下四个文档之间的关系。
比作一棵树,根茎枝干就是workerman,剩余的三个是其衍生作品,是叶子。

简单示例

在webman中装webman-admin,装gateway,简单实现http请求长连接,推送消息

workerman_第2张图片

workerman_第3张图片

workerman_第4张图片
workerman_第5张图片
![在这里插入图片描述](https://img-blog.csdnimg.cn/7c1c65aaa2e44805aaca383bfb637f2b.pngworkerman_第6张图片
workerman_第7张图片
workerman_第8张图片
workerman_第9张图片

tp6中的回调展示方法



namespace app\common;

use GatewayWorker\Lib\Gateway;
use Workerman\Lib\Timer;

class GatewayWorker
{
    
    //php think worker:gateway
    public static function onWebSocketConnect($client_id, $data)
    {
        //var_export($data);
        $token = isset($data['get']['token']) ? $data['get']['token'] : '';
        
        if (empty($token)) {
            Gateway::sendToCurrentClient("token传参异常");
            Gateway::closeClient($client_id);
            return;
        }
        
        $redis = newRedis();
        $user_info = $redis->hget('user_info', $token);
        if (!$user_info) {
            Gateway::sendToCurrentClient("非法token值");
            Gateway::closeClient($client_id);
            return;
        }
        
        //绑定uid
        Gateway::bindUid($client_id, $token);
        
        //开局给用户设置一个定时器id
        Gateway::setSession($client_id, ['time_id' => 0]);
    }
    
    //{"type": "to_msg","data": {"id": 2,"msg": "你在家吗"}}
    public static function onMessage($client_id, $data)
    {
        $result = json_decode($data, true);
        if (empty($result) || !isset($result['type'])) {
            Gateway::sendToClient($client_id, "请按规定传值");
            return;
        }
        
        switch ($result['type']) {
            //互发消息
            case 'to_msg':
                $is_online = Gateway::isUidOnline($result['data']['id']);
                if ($is_online) {
                    Gateway::sendToUid($result['data']['id'], $result['data']['msg']);
                } else {
                    Gateway::sendToClient($client_id, "用户id:" . $result['data']['id'] . "不在线");
                }
                break;
            
            //定时器
            case 'game':
                if ($_SESSION['time_id'] > 0) {
                    return;
                }
                
                $count = 5;
                //创建一个每秒执行一次的倒计时
                $_SESSION['time_id'] = $time_id = Timer::add(1, function() use (&$time_id, &$count, &$client_id) {
                    $leave_time = $count--;
                    if ($leave_time <= 1) {
                        //倒计时结束,删除定时器
                        Timer::del($time_id);
                        Gateway::updateSession($client_id, ['time_id' => 0]);
                        //强制分配给y,y不在线分配给z
                    }
                    //给用户推送倒计时剩余秒数
                    Gateway::sendToClient($client_id, $leave_time);
                    //执行匹配规则
                });
                break;
            
            //其余功能匹配
            default:
                Gateway::sendToClient($client_id, "其余功能未开放");
                break;
        }
    }
    
    public static function onClose($client_id)
    {
        //用户断开之后需要删除定时器
        if (isset($_SESSION['time_id']) && $_SESSION['time_id'] > 0) {
            Timer::del($_SESSION['time_id']);
        }
    }
}

tp6自定义command



declare(strict_types=1);

namespace app\command;

use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Config;
use Workerman\Worker;

class GatewayCommand extends Command
{
    protected function configure()
    {
        // windows下操作指令
        $this->setName('win_gateway')
            ->addArgument('service', Argument::OPTIONAL, 'workerman service: gateway|register|businessworker', null)
            ->addOption('host', 'H', Option::VALUE_OPTIONAL, 'the host of workerman server', null)
            ->addOption('port', 'P', Option::VALUE_OPTIONAL, 'the port of workerman server', null)
            ->addOption('daemon', 'd', Option::VALUE_OPTIONAL, 'Run the workerman server in daemon mode.')
            ->setDescription('Gateway Server for ThinkPHP in Windows');
    }

    protected function execute(Input $input, Output $output)
    {
        $service = $input->getArgument('service');

        $option = Config::get('gateway_worker');

        if ($input->hasOption('host')) {
            $host = $input->getOption('host');
        } else {
            $host = !empty($option['host']) ? $option['host'] : '0.0.0.0';
        }

        if ($input->hasOption('port')) {
            $port = $input->getOption('port');
        } else {
            $port = !empty($option['port']) ? $option['port'] : '2347';
        }

        $registerAddress = !empty($option['registerAddress']) ? $option['registerAddress'] : '127.0.0.1:1236';
        switch ($service) {
            case 'register':
                $this->register($registerAddress);
                break;
            case 'businessworker':
                $this->businessWorker($registerAddress, isset($option['businessWorker']) ? $option['businessWorker'] : []);
                break;
            case 'gateway':
                $this->gateway($registerAddress, $host, $port, $option);
                break;
            default:
                $output->writeln("Invalid argument action:{$service}, Expected gateway|register|businessworker .");
                exit(1);
                break;
        }

        Worker::runAll();
    }

    /**
     * 启动register
     * @access public
     * @param string $registerAddress
     * @return void
     */
    public function register($registerAddress)
    {
        // 初始化register
        new Register('text://' . $registerAddress);
    }

    /**
     * 启动businessWorker
     * @access public
     * @param string $registerAddress registerAddress
     * @param array $option 参数
     * @return void
     */
    public function businessWorker($registerAddress, $option = [])
    {
        // 初始化 bussinessWorker 进程
        $worker = new BusinessWorker();

        $this->option($worker, $option);

        $worker->registerAddress = $registerAddress;
    }

    /**
     * 启动gateway
     * @access public
     * @param string $registerAddress registerAddress
     * @param string $host 服务地址
     * @param integer $port 监听端口
     * @param array $option 参数
     * @return void
     */
    public function gateway($registerAddress, $host, $port, $option = [])
    {
        // 初始化 gateway 进程
        if (!empty($option['socket'])) {
            $socket = $option['socket'];
            unset($option['socket']);
        } else {
            $protocol = !empty($option['protocol']) ? $option['protocol'] : 'websocket';
            $socket = $protocol . '://' . $host . ':' . $port;
            unset($option['host'], $option['port'], $option['protocol']);
        }

        $gateway = new Gateway($socket, isset($option['context']) ? $option['context'] : []);

        // 以下设置参数都可以在配置文件中重新定义覆盖
        $gateway->name = 'Gateway';
        $gateway->count = 4;
        $gateway->lanIp = '127.0.0.1';
        $gateway->startPort = 2000;
        $gateway->pingInterval = 10;
        $gateway->pingNotResponseLimit = 1;
        $gateway->pingData = '{"type":"ping"}';
        $gateway->registerAddress = $registerAddress;

        // 全局静态属性设置
        foreach ($option as $name => $val) {
            if (in_array($name, ['stdoutFile', 'daemonize', 'pidFile', 'logFile'])) {
                Worker::${$name} = $val;
                unset($option[$name]);
            }
        }

        $this->option($gateway, $option);
    }

    /**
     * 设置参数
     * @access protected
     * @param Worker $worker Worker对象
     * @param array $option 参数
     * @return void
     */
    protected function option($worker, array $option = [])
    {
        // 设置参数
        if (!empty($option)) {
            foreach ($option as $key => $val) {
                $worker->$key = $val;
            }
        }
    }
}

windows.bat文件实现在windows下测试

start php think win_gateway register
start php think win_gateway businessworker
start php think win_gateway gateway

newredis


//公共方法
use think\facade\Config;

//redis
function newRedis($select = '')
{
    $config = Config::get('cache.stores.redis');
    $db = empty($config['select']) ? $config['select'] : $select;
    $redis = new \Redis();
    $redis->connect($config['host'], $config['port']);
    if (!empty($config['password'])) {
        $redis->auth($config['password']);
    }
    $redis->select($db);
    return $redis;
}

config


// +----------------------------------------------------------------------
// | 缓存设置
// +----------------------------------------------------------------------
return [
    // 默认缓存驱动
    'default' => env('cache.driver', 'file'),
    // 缓存连接方式配置
    'stores'  => [
        'file' => [
            // 驱动方式
            'type'       => 'File',
            // 缓存保存目录
            'path'       => '',
            // 缓存前缀
            'prefix'     => '',
            // 缓存有效期 0表示永久缓存
            'expire'     => 0,
            // 缓存标签前缀
            'tag_prefix' => 'tag:',
            // 序列化机制 例如 ['serialize', 'unserialize']
            'serialize'  => [],
        ],
        // 配置Reids
        'redis' => [
            'type' => 'redis',
            'host' => '127.0.0.1',
            'port' => '6379',
            'password' => '',
            'select' => '0',
            // 全局缓存有效期(0为永久有效)
            'expire' => 0,
            // 缓存前缀
            'prefix' => '',
            //默认缓存周期
            'timeout' => 3600,
        ],
    ],
];

你可能感兴趣的:(php)