RT,我是在thinkphp6中使用wokerman執(zhí)行異步任務(wù),主要是發(fā)送TCP請(qǐng)求給三方接口,因?yàn)槿教幚淼谋容^慢,所以設(shè)置了1個(gè)小時(shí)的超時(shí)時(shí)間,也就是代碼會(huì)在socket_read()
這里等待1小時(shí),但是當(dāng)我運(yùn)行workermanstatus
的命令后,會(huì)導(dǎo)致socket_read
這里立即返回,導(dǎo)致我設(shè)置的超時(shí)時(shí)間就失效,請(qǐng)問(wèn)這是怎么回事,該如何解決
我感覺(jué)和這個(gè)問(wèn)題很像,http://www.wtbis.cn/q/2367
因?yàn)樾枰ㄆ诓榭催M(jìn)程狀態(tài),我該如何避免這種情況發(fā)生
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//如果運(yùn)行workerman status 這里設(shè)置的超時(shí)時(shí)長(zhǎng)就失效了
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 3600, "usec" => 0));
socket_set_block($socket);
//self::log("tcp request:0001" );
if (@socket_connect($socket, self::getHost(), $port) === false) {
// 創(chuàng)建連接
socket_close($socket);
$message = sprintf("create socket error:%s", socket_strerror(socket_last_error()));
throw new TcpException($message);
}
//self::log("tcp request:0002" );
$length = strlen($msg);
//self::log("tcp request:0003" );
$result = @socket_write($socket, $msg, $length);
//self::log("tcp request:0004" );
unset($msg);
if (false === $result) {
//self::log("tcp request error:0002" );
socket_close($socket);
$message = sprintf("write socket error:%s", socket_strerror(socket_last_error()));
throw new TcpException($message);
}
$response = '';
$tmp = '';
$i = 0;
// socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 3600, "usec" => 0));
self::log('FeiDongAI TCP','socket_read Before');
while ($tmp = @socket_read($socket, 2048, PHP_BINARY_READ)) {
self::log('socket_read', $tmp . ' 序號(hào)' . $i++);
if (empty($tmp)) {
break;
}
$response .= $tmp;
}
self::log('socket_read while complete', $response);
// self::log('FeiDongAI TCP','socket_read Complete');
socket_close($socket);
if (empty($response)) {
return $response;
}
//self::log($response);
$response = json_decode(substr($response, 4), true);
$response = empty($response) ? [] : $response;
return $response; //self::log("request content", $msg);
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 3600, "usec" => 0));
socket_set_block($socket);
//self::log("tcp request:0001" );
if (@socket_connect($socket, self::getHost(), $port) === false) {
// 創(chuàng)建連接
socket_close($socket);
$message = sprintf("create socket error:%s", socket_strerror(socket_last_error()));
throw new TcpException($message);
}
//self::log("tcp request:0002" );
$length = strlen($msg);
//self::log("tcp request:0003" );
$result = @socket_write($socket, $msg, $length);
//self::log("tcp request:0004" );
unset($msg);
if (false === $result) {
//self::log("tcp request error:0002" );
socket_close($socket);
$message = sprintf("write socket error:%s",socket_strerror(socket_last_error()));
throw new TcpException($message);
}
$response = '';
$tmp = '';
while ($tmp = @socket_read($socket, 2048, PHP_BINARY_READ)) {
if (empty($tmp)) {
break;
}
$response .= $tmp;
}
socket_close($socket);
if (empty($response)) {
return $response;
}
$response = json_decode(substr($response, 4), true);
$response = empty($response) ? [] : $response;
return $response;
這個(gè)屬于網(wǎng)絡(luò)編程的知識(shí),status命令會(huì)觸發(fā)信號(hào),信號(hào)會(huì)打斷socket_read調(diào)用,socket_read會(huì)立刻返回false。
解決這個(gè)問(wèn)題需要自己加一個(gè)時(shí)間判斷,代碼類似
$timeout = 60;
$startTime = time();
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ['sec' => $timeout, 'usec' => 0]);
while (1) {
$tmp = @socket_read($socket, 2048, PHP_BINARY_READ);
if ($tmp === false) {
$code = socket_last_error($socket);
socket_clear_error($socket);
if ($code !== 4) {
break;
}
// socket被信號(hào)打斷
$leftTimeout = $timeout - (time() - $startTime);
echo $leftTimeout,"\n";
if ($timeout <= 0) {
break;
}
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ['sec' => $leftTimeout, 'usec' => 0]);
continue;
}
if ($tmp === '') {
break;
}
$response .= $tmp;
}