一開(kāi)始正常,運(yùn)行10分鐘后,就會(huì)出錯(cuò),Gateway::getAllGroupIdList()返回的數(shù)據(jù)會(huì)缺失一部分。
環(huán)境:php8.0.1到8.0.7都會(huì)出現(xiàn)這個(gè)問(wèn)題。
提取了可重現(xiàn)代碼如下:
<?php
use GatewayClient\Gateway;
use Swoole\Process;
require __DIR__.'/../vendor/autoload.php';
$Test = new test();
$Test->SwooleRundebug2();
class test{
public function SwooleRundebug2(){
// 監(jiān)聽(tīng)一個(gè)http端口,端口只暴露給nginx
global $Server;
$Server = new Swoole\Http\Server('0.0.0.0', 16985); // SWOOLE_BASE 不支持reload
$Server->set(['enable_coroutine' => false,'worker_num' => 1,]);
$Server->on('WorkerStart', function ($server, $worker_id){
Swoole\Timer::tick(3000, function () {
$this->subProcess();
});
});
$Server->on('request', function ($request, $response){
});
$Server->start();
}
public function subProcess()
{
Swoole\Process::wait(false);
// 開(kāi)啟子線程
$process = new Process(function (Process $proc) {
echo '開(kāi)始運(yùn)行一次', date('Y-m-d H:i:s');
// 運(yùn)行這個(gè) 獲取rooms
Gateway::$registerAddress = '127.0.0.1:9138';
$rooms = Gateway::getAllGroupIdList();
var_dump($rooms);
if(empty($rooms)){
Gateway::$registerAddress = '127.0.0.1:9138';// 這里打斷點(diǎn),方便調(diào)試
$rooms = Gateway::getAllGroupIdLsist();
}
$proc->exit();
}, false, 1, true);
$process->start();
}
}
經(jīng)過(guò)xdebug調(diào)試發(fā)現(xiàn),在 vendor\workerman\gatewayclient\Gateway.php的方法
protected static function getBufferFromGateway($gateway_buffer_array)
中的這一段代碼有問(wèn)題
while (count($client_array) > 0) {
$write = $except = array();
$read = $client_array;
if (@stream_select($read, $write, $except, $timeout)) {
foreach ($read as $client) {
$socket_id = (int)$client;
$buffer = stream_socket_recvfrom($client, 65535);
if ($buffer !== '' && $buffer !== false) {
$receive_buffer_array[$socket_id] .= $buffer;
$receive_length = strlen($receive_buffer_array[$socket_id]);
if (empty($recv_length_array[$socket_id]) && $receive_length >= 4) {
$recv_length_array[$socket_id] = current(unpack('N', $receive_buffer_array[$socket_id]));
}
if (!empty($recv_length_array[$socket_id]) && $receive_length >= $recv_length_array[$socket_id] + 4) {
unset($client_array[$socket_id]);
}
} elseif (feof($client)) {
unset($client_array[$socket_id]);
}
}
}
if (microtime(true) - $time_start > $timeout) {
break;
}
}
這里會(huì)訪問(wèn)4個(gè)端口獲取數(shù)據(jù),但是只有一個(gè)端口能得到數(shù)據(jù),其他的端口獲取不到數(shù)據(jù)。求大佬解決 @walkor
有問(wèn)題的時(shí)候運(yùn)行status截圖下,截圖截全。
常駐內(nèi)存下 Gateway client 出問(wèn)題了 ,會(huì)拿不到數(shù)據(jù),不知道和 socket 沒(méi)有 close 有沒(méi)有關(guān)系