HEX
Server: nginx/1.28.1
System: Linux 10-41-63-61 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 20 00:40:06 UTC 2024 x86_64
User: www (1001)
PHP: 7.4.33
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
File: /www/wwwroot//my.esfyn.top/Expand/Swoole/MySwoole.php
<?php


namespace Expand\Swoole;

use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Facade;
use Swoole\Process;

class MySwoole
{

    use Console, \Expand\Swoole\Process;

    public $http;

    /**
     * @var \Illuminate\Contracts\Container\Container
     */
    public $app;

    public static $instance;

    /**
     * @var array|mixed
     */
    public $config = [];

    public function __construct()
    {
        $this->config = require "config.php";

        $this->initHttp();
    }

    public static function getInstance(): MySwoole
    {
        if (!(self::$instance instanceof self)) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * 初始化服务器
     */
    public function initHttp()
    {
        if (!$this->isRunning()) {

            $this->http = new \swoole_http_server($this->config['host'], $this->config['port']);

            $this->http->set([
                'worker_num' => $this->config['worker_num'],
                'max_request' => $this->config['max_request'],
                'daemonize' => true,
            ]);

            $this->http->on('WorkerStart', [$this, 'onWorkerStart']);
            $this->http->on('request', [$this, 'onRequest']);
            $this->http->on('start', [$this, 'onStart']);
        }
    }


    /**
     * 运行统一入口
     * @param $argv
     */
    public function run($argv)
    {
        if (isset($argv[1]) && method_exists($this, $argv[1])) {
            $this->{$argv[1]}();
        }
    }

    /**
     * 启动服务
     */
    public function start()
    {
        !$this->http && $this->initHttp();

        if (!$this->isRunning()) {

            $this->info('MyCms start success!');
            $this->http->start();
        }

        $this->isRunning() && $this->info('MyCms is running!');
    }

    /**
     * 重载服务
     */
    public function reload()
    {
        if ($this->isRunning()) {
            $this->http->reload();
        }
    }

    /**
     * 停止服务
     */
    public function stop()
    {
        $masterPid = $this->read()[0];
        Process::kill($masterPid, SIGTERM);

        $start = time();

        do {

            if (!$this->isRunning()) {
                break;
            }

            usleep(100000);

        } while (time() < $start + 15);

        unlink($this->config['pid_file']);

        $this->info('MyCms stop success!');

    }

    /**
     * 重启服务
     */
    public function restart()
    {

        $this->isRunning() && $this->stop();

        $this->start();
    }

    /**
     * 判断服务是否在运行
     */
    public function isRunning(): bool
    {
        if (!is_file($this->config['pid_file'])) {
            return false;
        }

        list($masterPid, $managerPid) = $this->read();

        if ($managerPid) {

            return $masterPid && Process::kill((int)$managerPid, 0);
        }

        return $masterPid && Process::kill((int)$masterPid, 0);
    }

    public function onStart($server)
    {
        $this->info('MyCms start success!');
        $this->write($server->master_pid . ',' . $server->manager_pid);
    }

    public function onWorkerStart($server, $workId)
    {
        if (extension_loaded('apc')) {
            apc_clear_cache();
        }

        if (extension_loaded('Zend OPcache')) {
            opcache_reset();
        }

        require ROOT_PATH . '/vendor/autoload.php';

        $this->app = require ROOT_PATH . '/bootstrap/app.php';
    }

    /**
     * @throws BindingResolutionException
     */
    public function onRequest($req, $res)
    {

        $request = Request::create(
            $req->server['request_uri'],
            $req->server['request_method'],
            array_merge($req->get ?? [], $req->post ?? []),
            $req->cookie ?? [],
            $req->files ?? [],
            $this->transformServerParameters($req->server ?? [], $req->header ?? []),
            $req->rawContent()
        );

        $kernel = $this->app->make(Kernel::class);

        $response = $kernel->handle($request);

        $res->status($response->getStatusCode());

        foreach ($response->headers->allPreserveCaseWithoutCookies() as $name => $values) {
            foreach ($values as $value) {
                $res->header($name, $value, false);
            }
        }

        foreach ($response->headers->getCookies() as $cookie) {
            $res->header('Set-Cookie', $cookie->getName() . strstr($cookie, '='), false);
        }

        $res->end($response->getContent());

        $this->resetProviders();

    }

    /**
     * 每次都需要重新加载的服务
     */
    protected function resetProviders()
    {
        foreach ($this->config['resets'] as $provider) {

            if (class_exists($provider)) {

                $provider = new $provider($this->app);
                $provider->reset();
            }
        }
    }

    /**
     * 请求 server 转换
     */
    protected function transformServerParameters(array $server, array $header): array
    {
        $__SERVER = [];

        foreach ($server as $key => $value) {
            $key = strtoupper($key);
            $__SERVER[$key] = $value;
        }

        foreach ($header as $key => $value) {
            $key = str_replace('-', '_', $key);
            $key = strtoupper($key);

            if (!in_array($key, ['REMOTE_ADDR', 'SERVER_PORT', 'HTTPS'])) {
                $key = 'HTTP_' . $key;
            }

            $__SERVER[$key] = $value;
        }

        return $__SERVER;
    }

}