通過 stop -g 或者 kill -SIGHUP 來優(yōu)雅結(jié)束進(jìn)程, 接收到信號后在onWorkerStop中該如何處理?等待業(yè)務(wù)處理完畢后exit還是把所有的連接都銷毀掉?在mqtt client中好像并沒有可以將$this->_connection
設(shè)置為null的方法
偽代碼
$worker->onWorkerStop = function(){
/**
* @var Client
*/
global $mqtt;
$mqtt->disconnect();
exit(0);
};
$worder->onWokerStop = function(){
global $client;
$client->destory();
$client = null;
};
demo:
<?php
use Workerman\Worker;
use Workerman\Mqtt\Client;
require_once('vendor/autoload.php');
var_dump(posix_getpid());
$worker = new Worker('text://127.0.0.1:1234');
$worker->onWorkerStart = function(){
try {
$username = 'abc';
$password = 'abc';
$clientId = 'abc';
global $mqtt;
$mqtt = new Client('mqtt://emqx:1883', [
'client_id' => $clientId,
'username' => $username,
'password' => $password,
'debug' => true
]);
$mqtt->connect();
} catch (\Throwable $th) {
echo (string) $th . PHP_EOL;
return;
}
};
$worker->onMessage = function($connection, $buffer){
try {
$data = json_decode($buffer, true);
if(empty($data)){
throw new Exception('data error');
}
if(empty($data['topic']) || !is_string($data['topic']) || empty($data['message']) || !is_string($data['message']) ){
throw new Exception('data error');
}
global $mqtt;
$mqtt->publish($data['topic'], $data['message']);
} catch (\Throwable $th) {
echo (string) $th . PHP_EOL;
return;
}
};
$worker->onWorkerStop = function($worker){
/**
* @var Client
*/
global $mqtt;
if($mqtt){
$mqtt->disconnect();
$mqtt = null;
}
Worker::stopAll();
};
Worker::runAll();
也嘗試過在 Worker::stopAll() 前將$worker->onWorkerStop=null
, 但是此時的連接對象并不會銷毀,沒有執(zhí)行連接對象的析構(gòu)函數(shù)里,連接數(shù)不會--,進(jìn)程依然沒有結(jié)束。
foreach (\Workerman\Connection\TcpConnection::$connections as $connection) {
$connection->close();
}
onWorkerStop里這樣關(guān)閉所有連接,應(yīng)該就退出了。不用再執(zhí)行Worker::stopAll();了
在 $mqtt->disconnect();時連接已經(jīng)被關(guān)閉了,但是該連接的對象并沒有被銷毀,沒有在對象的析構(gòu)函數(shù)中減少連接數(shù)。
多次嘗試之后,目前感覺需要在mqtt client中增加一個destory方法用來銷毀connection對象。使得連接數(shù)在connection對象的析構(gòu)函數(shù)中減一。
worker 偽代碼
$worker->onWorkerStop = function($worker){
/**
* @var Client
*/
global $mqtt;
if($mqtt){
$mqtt->destory();
$mqtt = null;
}
};
mqtt client 偽代碼
public function destory(): void
{
$this->disconnect();
$this->_connection = $this->onConnect = $this->onReconnect = $this->onMessage = $this->onClose = $this->onError = null;
}
增加該方法之后 mqtt client 中部分方法可能需要做兼容可能才會更友好,比如close方法中$this->_connection->destroy()
前需要對$this->_connection
是否為空的判斷