我正在向API发送测试卷曲请求,以测试接收数据并在进程持续超过15秒时取消请求。问题是30秒后数据返回,我必须检查等待它是否需要超过15秒。这是我做的:
for($x=0; $x<$quantity; $x++){
$xmlRequest = "<?xml version='1.0' encoding='utf-8'?>
<REQUEST TYPE='PINPRINTING' MODE='DIRECT'>
<AMOUNT>" . $amount . "</AMOUNT>
<PRODUCTID>" . $comp_id . "</PRODUCTID>
<USERNAME>Username</USERNAME>
<PASSWORD>Password</PASSWORD>
</REQUEST>";
$url = "URL-HERE";
$headers = array(
"Content-type: text/xml;charset=\"utf-8\"",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: \"run\""
);
try {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$data = curl_exec($ch);
$now = time();
$later = time();
for($i=1; $i<16; $i++){
if(!is_array($data)){
sleep(1);
$later += $i;
if( ($later - $now) >= 15 ){
echo $now.'<br>'.$later.'<br>';
echo '<p>It passed 15 seconds</p>';
$xmlRequest1 = "<?xml version='1.0' encoding='utf-8'?>
<REQUEST TYPE='CANCEL'>
<AMOUNT>" . $amount . "</AMOUNT>
<PRODUCTID>" . $comp_id . "</PRODUCTID>
<USERNAME>Username</USERNAME>
<PASSWORD>Password</PASSWORD>
</REQUEST>";
$headers = array(
"Content-type: text/xml;charset=\"utf-8\"",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: \"run\""
);
try {
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_URL, $url);
curl_setopt($ch1, CURLOPT_POST, 1);
curl_setopt($ch1, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch1, CURLOPT_POSTFIELDS, $xmlRequest1);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_VERBOSE, 0);
curl_setopt($ch1, CURLOPT_HTTPHEADER, $headers);
$data = curl_exec($ch1);
print_r($data);
curl_close($ch1);
}
catch (Exception $e) {
echo 'error occurred<br>';
echo 'Message: ' . $e->getMessage();
}
die('Error');
}
}
else{
if ($data === false) {
$error = curl_error($ch);
echo $error;
die('error occurred');
}
else {
$data = json_decode(json_encode(simplexml_load_string($data)), true);
if($data['RESULTTEXT'] == 'transaction successful'){
print_r($data);
}
else{
echo "Error: ".$data['RESULTTEXT']."<p>";
}
}
}
}
curl_close($ch);
}
catch (Exception $e) {
echo '<p>Message: ' . $e->getMessage();
die("Error");
}
}
我创建了一个内部循环,每秒检查一次,如果$ data不是一个发送取消请求的数组,但问题是它会等待30秒(整个时间过程来获取数据,即使它无效)而不是15秒。
我想要做的是每隔15秒检查一次是否收到数据。如果没有收到,它应该发送取消请求,而不必等待整个30秒,如果有效则不发送请求15次,所以如果有数据应该只执行一次并退出内部循环继续外循环( for(x = 0)...)
答案 0 :(得分:0)
这是一个例子, a.html - 包含GUI控件和javascript,它计算已经过了多少秒,并允许您在认为它已经过长时间时中止(例如,在15秒后中止)
<input id="startRequest" type="button" value="start request" /><br/>
<input id="abortRequest" type="button" value="abort request" /><br/>
seconds running: <span id="runtimeCounter">not started yet</span><br/>
<span id="response">the xhr response will be added here by javascript</span>
<script>
window.xhr;
function count(){
var xhr=window.xhr;
var ele=document.querySelector("#runtimeCounter");
if(!xhr.aborted && xhr.readyState<4){
ele.textContent=Number(ele.textContent)+1;
}else{
ele.textContent+=" completed!";
clearTimeout(window.count.clearid);
}
}
document.querySelector("#startRequest").addEventListener("click",function(){
document.querySelector("#runtimeCounter").textContent=0;
var xhr=window.xhr=new XMLHttpRequest();
xhr.open("POST","xhr.php");
xhr.addEventListener("progress",function(ev){
var xhr=ev.target;
document.querySelector("#response").textContent=xhr.responseText;
});
xhr.send();
window.count.clearid=setTimeout(count,1000);
});
document.querySelector("#abortRequest").addEventListener("click",function(){
var xhr=window.xhr;
xhr.abort();
xhr.aborted=true;
document.querySelector("#runtimeCounter").textContent+=" - aborted";
});
</script>
和xhr.php,实际上是卷曲的东西:
for($x = 0; $x < $quantity; ++$x) {
$xmlRequest = "<?xml version='1.0' encoding='utf-8'?>
<REQUEST TYPE='PINPRINTING' MODE='DIRECT'>
<AMOUNT>" . $amount . "</AMOUNT>
<PRODUCTID>" . $comp_id . "</PRODUCTID>
<USERNAME>Username</USERNAME>
<PASSWORD>Password</PASSWORD>
</REQUEST>";
$url = "URL-HERE";
$headers = array (
"Content-type: text/xml;charset=\"utf-8\"",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: \"run\""
);
try {
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $xmlRequest );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 0 );
curl_setopt ( $ch, CURLOPT_VERBOSE, 0 );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
$data = curl_exec ( $ch );
curl_close ( $ch );
} catch ( Exception $e ) {
echo '<p>Message: ' . $e->getMessage ();
die ( "Error" );
}
}
请注意我如何将CURLOPT_RETURNTRANSFER设置为0,因为这允许javascript在进展时监控下载 - 而不是像最后一样发送所有内容,如RETURNTRANSFER必须这样做(它还节省了服务器ram btw,因为下载的内容是只是存储,直到它被发送到客户端,分批,并丢弃,而不是将所有内容存储在RAM中直到100%下载)
ignore_user_abort(true);
,则中止按钮将不起作用