ソースを参照

fix(worker): 修复Workerman命令行控制功能

- 引入Workerman\Worker类以支持底层状态查询功能
- 重构handle方法,优化启动流程并修复原生启动逻辑
- 通过重置全局$argv解决父类私有变量导致的命令识别问题
- 实现status和connections查询功能,复用Workerman原生输出逻辑
- 统一信号控制处理机制,改进错误提示信息
- 移除环境检测相关代码,简化启动配置逻辑
runphp 2 日 前
コミット
afdf7825b6
1 ファイル変更54 行追加23 行削除
  1. 54 23
      src/Command/WorkerCommand.php

+ 54 - 23
src/Command/WorkerCommand.php

@@ -8,6 +8,7 @@ use think\console\input\Argument;
 use think\console\input\Option;
 use think\worker\command\Server;
 use think\worker\Manager;
+use Workerman\Worker;
 
 class WorkerCommand extends Server
 {
@@ -17,40 +18,70 @@ class WorkerCommand extends Server
             ->addArgument('action', Argument::OPTIONAL, 'start|stop|restart|reload|status|connections', 'start')
             ->addOption('daemon', 'd', Option::VALUE_NONE, 'daemon mode')
             ->addOption('grace', 'g', Option::VALUE_NONE, 'graceful shutdown/reload')
-            ->setDescription('Workerman Server for ThinkPHP (with env detection)');
+            ->setDescription('Workerman Server for ThinkPHP (custom entry)');
     }
 
     public function handle(Manager $manager)
     {
-        $action  = $this->input->getArgument('action') ?: 'start';
-        $grace   = $this->input->getOption('grace');
+        $action = $this->input->getArgument('action') ?: 'start';
+        $grace = $this->input->getOption('grace');
 
-        // think\worker\Worker 禁用了 parseCommand(),需手动处理控制命令
-        if ($action !== 'start') {
-            $pidFile = runtime_path() . 'worker.pid';
-            $masterPid = is_file($pidFile) ? (int) file_get_contents($pidFile) : 0;
-
-            if ($masterPid <= 0 || !posix_kill($masterPid, 0)) {
-                $this->output->error('Worker is not running');
-                return;
+        // 启动流程,直接使用框架原生启动逻辑
+        if ($action === 'start') {
+            if ($grace) {
+                putenv('WORKER_GRACE=1');
             }
+            $manager->start();
+            return;
+        }
 
-            match ($action) {
-                'stop'  => posix_kill($masterPid, $grace ? SIGQUIT : SIGINT),
-                'reload' => posix_kill($masterPid, $grace ? SIGUSR2 : SIGUSR1),
-                'restart' => posix_kill($masterPid, $grace ? SIGQUIT : SIGINT),
-                default  => null,
-            };
+        // 1. 重置全局$argv,绕过父类私有static::$command,底层getArgv正常识别指令
+        global $argv;
+        $argv = [
+            PHP_BINARY,
+            'think',
+            'worker',
+            $action
+        ];
+        if ($grace) {
+            $argv[] = '-g';
+        }
 
-            $this->output->info("Worker {$action} signal sent");
+        $pidFile = runtime_path() . 'worker.pid';
+        $masterPid = file_exists($pidFile) ? (int)file_get_contents($pidFile) : 0;
+        // 检测进程是否运行
+        if ($masterPid <= 0 || !posix_kill($masterPid, 0)) {
+            $this->output->error('Worker is not running');
             return;
         }
 
-        $envName = getenv('RUNTIME_ENVIRONMENT') ?: '';
-        if (getenv('IS_DDEV_PROJECT') == 'true') {
-            $envName = 'ddev';
+        match ($action) {
+            // 查询类:调用Workerman底层原生打印表格逻辑
+            'status', 'connections' => $this->renderWorkerStatus(),
+
+            // 信号控制类
+            'stop' => posix_kill($masterPid, $grace ? SIGQUIT : SIGINT),
+            'reload' => posix_kill($masterPid, $grace ? SIGUSR2 : SIGUSR1),
+            'restart' => posix_kill($masterPid, $grace ? SIGQUIT : SIGINT),
+
+            default => $this->output->error("Unknown action: {$action}"),
+        };
+
+        // 非查询指令输出提示
+        if (!in_array($action, ['status', 'connections'])) {
+            $this->output->info("{$action} signal sent to master PID: {$masterPid}");
         }
-        $_ENV['ENV_NAME'] = $envName;
-        $manager->start();
+    }
+
+    /**
+     * 复用Workerman底层 status / connections 原生输出逻辑
+     */
+    protected function renderWorkerStatus(): void
+    {
+        Worker::$pidFile = runtime_path() . 'worker.pid';
+        Worker::$statusFile = runtime_path() . 'worker.status';
+        Worker::$logFile = runtime_path() . 'worker.log';
+        // 底层自动读取重写后的$argv,输出进程/连接表格
+        Worker::runAll();
     }
 }