GatewayWorker的onWorkerStart方法中如何获得单进程的id

ximengxuan

在GatewayWorker的onWorkerStart方法中,调用了Crontab模块。
gateway进程数设置为4,经过测试,发现每次执行都会出现4个结果。
有什么办法能让Crontab模块只执行1次,而不是执行多次呢?

使用$pid = posix_getpid()方法,获取到的是5位数的id,数字是随机的,并不固定。
有什么办法能获得$pid映射的$worker_id,结果如0、1、2、3这样的呢?

//GatewayWorker/Applications/YourApp/Events.php

use Workerman\Crontab\Crontab;

public static function onWorkerStart($businessWorker)
    {
        // 每分钟的第1秒执行.
        self::$crontab = new Crontab('1 * * * * *', function () {
            // echo date('Y-m-d H:i:s') . "\n";

            echo posix_getpid() . "\n";
        });
    }

输出内容:

13080
13091
13093
13094

还有一个问题,就是打印$businessWorker这个参数,输出的是null。这个是什么原因呢?

441 3 0
3个回答

ximengxuan

测试了一下,设置$worker->count = 1;
就可以实现Crontab模块只执行1次。
不知道还有没有其他更好的办法?

  • 暂无评论
ximengxuan

通过查询开发手册和论坛搜索,目前已找到另外两种办法。
1、在start_gateway.php所在目录里建立一个start_worker.php,内容类似

<?php

use Workerman\Worker;
use Workerman\Timer;

require_once __DIR__ . '/../../vendor/autoload.php';

$worker = new Worker("http://0.0.0.0:1258");

// 回调函数
$worker->onWorkerStart = function ($worker) {
    Timer::add(3, function () {
        echo posix_getpid() . "——" . date('Y-m-d H:i:s') . "\n";
    });
};

if (!defined('GLOBAL_START')) {
    Worker::runAll();
}

以上内容来自https://www.workerman.net/q/8853

2、添加一个回调函数:

//GatewayWorker/Applications/YourApp/start_businessworker.php

use \Workerman\Timer;

$worker->onWorkerStart = function ($worker) {
    // 只在id编号为0的进程上设置定时器,其它1、2、3号进程不设置定时器
    if ($worker->id === 0) {
        Timer::add(3, function () {
            echo "4个worker进程,只在0号进程设置定时器\n";
        });
    } else {
        echo "worker->id={$worker->id}\n";
    }
};
  • 暂无评论
walkor

也可以这样Event.php里

calss Event
{
   public static function onWorkerStart($worker)
   {
       if($worker->id = 0) {

       }
   }
}
  • ximengxuan 2023-06-11

    这样会报错的。
    Deprecated: call_user_func() expects parameter 1 to be a valid callback, non-static method Events::onWorkerStart() should not be called statically in /www/wwwroot/api.xxx.cn/GatewayWorker/vendor/workerman/gateway-worker/src/BusinessWorker.php on line 214

  • walkor 2023-06-11

    public static function onWorkerStart($worker)

  • ximengxuan 2023-06-11

    对啊,我是这样实现的。文件路径是“GatewayWorker/Applications/YourApp/Events.php”,在Events类下,public static function onWorkerStart($businessWorker),无法打印$businessWorker

  • walkor 2023-06-11

    检查下加没加 static

  • ximengxuan 2023-06-11

    直接复制您上面的代码,放在Events类里。启动服务后,会拼命地打印“ Gateway: Worker->name conflict. Key:127.0.0.1:YourAppBusinessWorker:0”

  • walkor 2023-06-11

    如果启动多组BusinessWorker,BusinessWorker->name不能一样

🔝