php使用fsockopen实现异步任务
2023-10-11 本文已影响0人
耍帅oldboy
一、发送异步任务
function asyncRequest($url,$timeout=10, $param = array())
{
$errno = 0;
$errstr = '';
$info=parse_url($url);
if(!isset($info['port'])){
$info['port'] = 80;
}
$query = json_encode($param,JSON_UNESCAPED_UNICODE); // 数组转url 字符串形式
$contextOptions = [
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false
]
];
$context = stream_context_create($contextOptions);
if($info['port']==443){
$fp = @stream_socket_client("ssl://{$info['host']}:{$info['port']}", $errno, $errstr, $timeout,STREAM_CLIENT_CONNECT,$context);
}else{
$fp = @stream_socket_client("{$info['host']}:{$info['port']}", $errno, $errstr, $timeout);
}
if (!$fp){
return "连接失败";
}
if ($errno || !$fp){
return $errstr;
}
stream_set_blocking($fp,0); // 非阻塞
stream_set_timeout($fp,1);// 相应超时时间(s)
$header = "POST ".$info['path']." HTTP/1.1\r\n";
$header .= "Host:". $info['host'] ."\r\n";
$header .= "Referer: ".$url."\r\n";;
$header .= "Content-type: application/json\r\n";
$header .= "Content-Length:" . strlen($query) . "\r\n";
$header .= "connection:close\r\n\r\n";
$header .= $query;
$result = fwrite($fp, $header);
usleep(200);//不加不会运行
fclose($fp);//关闭链接
return $result;
}
//调用方法
$a = asyncRequest('http://www.abc.com/consume',10,['params'=>['a'=>1,'b'=>2,'time'=>date('Y-m-d H:i:s')],'method'=>'xxxxx']);
二、执行异步任务
function consume()
{
set_time_limit(0);
ignore_user_abort(true);//设置与客户机断开是否会终止执行
if (function_exists("fastcgi_finish_request")){ // 部署在非fpm环境下fastcgi_finish_request()不存在
fastcgi_finish_request();//提高请求的处理速度
}
$data['post'] = $request->param();
$data['pid'] = getmypid();
call_user_func($data['post']['method'],$data['post']['params']);
//file_put_contents(time().'.txt',json_encode($data,JSON_UNESCAPED_UNICODE)); //打印参数可以查看
}