我使用TP框架的command 結(jié)合 workerman 來(lái)使用。
具體是在command里新建2個(gè)文件,然后通過php think PriceOkex start 、php think PriceBinance start 來(lái)啟動(dòng),發(fā)現(xiàn)只能啟動(dòng)一個(gè),另一個(gè)直接報(bào)錯(cuò)說worker已經(jīng)在執(zhí)行了。報(bào)錯(cuò)內(nèi)容
Workerman[think] start in DEBUG mode
Workerman[think] already running
應(yīng)該是 入口文件 think 重名了,有沒有什么方式讓workerman 以 think文件后面一個(gè)參數(shù)(比如上面的PriceOkex、PriceBinance)作為這個(gè)key ?
文件內(nèi)容如下
<?php
declare (strict_types=1);
namespace app\command;
use Workerman\Connection\AsyncTcpConnection;
use Workerman\Worker;
class PriceOkex extends Command
{
protected function configure()
{
// 指令配置
$this->setName('PriceOkex')
->addArgument('action', Argument::OPTIONAL,
"start|stop|restart|reload|status|connections", 'start')
->addOption('mode', 'm', Option::VALUE_OPTIONAL,
'Run the workerman server in daemon mode.')
->setDescription('the workerman command');
}
protected function execute(Input $input, Output $output)
{
// 指令輸出
$output->writeln('convert start');
$action = $input->getArgument('action');
$mode = $input->getOption('mode');
// 重新構(gòu)造命令行參數(shù),以便兼容workerman的命令
global $argv;
$argv = [];
array_unshift($argv, 'think', $action);
if ($mode == 'd') {
$argv[] = '-d';
} else {
if ($mode == 'g') {
$argv[] = '-g';
}
}
$worker_1 = new Worker();
$worker_1->name = 'PriceOkex';
$worker_1->id = 2;
$worker_1->onWorkerStart = function ($worker) {
$pRedis = Predis::getInstance();
$con = new AsyncTcpConnection('ws://ws.okx.com:8443/ws/v5/public');
$con->transport = 'ssl';
$con->onConnect = function (AsyncTcpConnection $con) {
};
$con->onMessage = function (AsyncTcpConnection $con, $data) use (
$pRedis
) {
};
$con->connect();
};
Worker::runAll();
}
}
另一個(gè)文件如下
<?php
declare (strict_types=1);
namespace app\command;
use Workerman\Connection\AsyncTcpConnection;
use Workerman\Worker;
class PriceBinance extends Command
{
protected function configure()
{
// 指令配置
$this->setName('PriceBinance')
->addArgument('action', Argument::OPTIONAL,
"start|stop|restart|reload|status|connections", 'start')
->addOption('mode', 'm', Option::VALUE_OPTIONAL,
'Run the workerman server in daemon mode.')
->setDescription('the workerman command');
}
protected function execute(Input $input, Output $output)
{
// 指令輸出
$output->writeln('convert start');
$action = $input->getArgument('action');
$mode = $input->getOption('mode');
// 重新構(gòu)造命令行參數(shù),以便兼容workerman的命令
global $argv;
$argv = [];
array_unshift($argv, 'think', $action);
if ($mode == 'd') {
$argv[] = '-d';
} else {
if ($mode == 'g') {
$argv[] = '-g';
}
}
$worker_1 = new Worker();
$worker_1->name = 'PriceBinance';
$worker_1->id = 1;
$worker_1->onWorkerStart = function ($worker) {
$pRedis = Predis::getInstance();
$con
= new AsyncTcpConnection('ws://stream.binance.com:9443/ws/btcusdt@aggTrade');
$con->transport = 'ssl';
$con->onConnect = function (AsyncTcpConnection $con) {
};
$con->onMessage = function (AsyncTcpConnection $con, $data) use (
$pRedis
) {
};
$con->connect();
};
Worker::runAll();
}
}
你這種做法類似于想復(fù)制N份 start.php ,然后想
php start.php start -d
php start1.php start -d
php start2.php start -d
按我個(gè)人理解,你這種做法是不正確的,thinkphp里面,如果想定義多個(gè)worker 服務(wù),
,正確做法是在配置的worker_class 里面設(shè)置自定義服務(wù)
'worker_class' => [],
// 自定義Workerman服務(wù)類名 支持?jǐn)?shù)組定義多個(gè)服務(wù)
如果沒有指定Worker::$pidFile,workerman會(huì)根據(jù)啟動(dòng)的文件名字來(lái)生成一個(gè)pid文件,thinkphp命令行里就是用thinkphp來(lái)自動(dòng)生成一個(gè)pid文件。這樣當(dāng)執(zhí)行stop status等命令時(shí),就能找到主進(jìn)程的pid,才能和對(duì)應(yīng)的進(jìn)程交互。
php think PriceOkex start
、php think PriceBinance start
這2個(gè)命令使用的是相同的thinkphp文件,所以pid一樣,無(wú)法重復(fù)啟動(dòng)。
解決辦法是根據(jù)參數(shù)不同,設(shè)置不同的Worker::$pidFile。
比如php think PriceOkex start
時(shí)代碼里動(dòng)態(tài)設(shè)置 Worker::$pidFile = '/var/run/PriceOkex.pid';
,這樣用thinkphp命令行啟動(dòng)多個(gè)服務(wù),互相不影響。
我在laravel 5.5 commands中使用Workerman遇到了同樣的問題,兩個(gè)不同的command,都設(shè)置了各自不同的pidFile,但是在使用 php artisan 啟動(dòng)其中一個(gè)時(shí),另外一個(gè)也會(huì)被啟動(dòng),此時(shí)只有一個(gè)pidFile生成,但是兩個(gè)command中的Worker進(jìn)程都被啟動(dòng)了