这是我一直在处理的一个老问题,但仍然没有解决方案,所以尝试新方法。
如何尽早发送SOAP响应(在脚本执行结束之前)?
如果在30秒之前未发送ACK文件,则会导致这些问题,因为此过程需要更长时间才能完成,然后才能完成分配时间。
flush()无效,得到此错误:
org.xml.sax.SAXParseException:XML文档结构必须在同一实体内开始和结束。
没有flush()我得到了这个
org.xml.sax.SAXParseException:文件过早结束。
脚本进程可能需要180秒才能完成,等待响应的服务器只会在超时前等待大约30秒(导致上述错误)。
关于我如何解决这个问题的任何想法?
以下是一些代码:这是我接受并发送即将发送的SOAP请求的ACK文件的方式
$data = 'php://input';
$content = file_get_contents($data);
if($content) {
respond('true');
} else {
respond('false');
}
回复功能
function respond($tf) {
$ACK = <<<ACK
<?xml version = "1.0" encoding = "utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<notifications xmlns="http://soap.sforce.com/2005/09/outbound">
<Ack>$tf</Ack>
</notifications>
</soapenv:Body>
</soapenv:Envelope>
ACK;
print trim($ACK);
}
PHP使用单线程处理方法,并且在线程完成处理之前不会发回ACK文件。在ACK提交后是否有某种方法可以关闭套接字并继续处理,因此我不会在发送服务器上出现这些超时问题?
答案 0 :(得分:1)
a)(可选)您可以使用set_time_limit()来增加执行时间的时间限制。
b)您必须增加wsdl客户端对象的时间,例如:
$clientwsdl->setOpt('timeout', 300); // if you are using PEAR:SOAP.
大多数wsdl类允许定义超时。
c)而不是,你不能尽早使用SOAP,而不是至少使用一个调用。考虑到SOAP返回一个XML,因此部分XML通常是无效的(它会错过结束标记)。
d)替代,您可以使用除SOAP之外的其他方法,例如阅读网址:
$fp=fopen("http://www.mysite.com/url.php","r");
其中url.php返回列(或某种值而不使用xml:
30|50|70|80|20
30|50|70|80|20
30|50|70|80|20
答案 1 :(得分:1)
据我所知,我们无法对30秒的限制做任何事情,并且在脚本完成之前不会刷新输出。你能尝试将你的处理逻辑分成两部分吗?
“要完成的工作”可能是一个新生成的过程(查看pcntl_fork()函数的注释,但对我来说看起来不太有希望)或某种方式将数据存储在文件中或数据库并定期用另一个脚本处理它,例如计划每5分钟运行一次?
如果60秒会以某种方式拯救你,你可以将你的出站信息重写为Apex的标注。基本上,您然后编写自己的SOAP信封并将其发送到任何http地址。你可以把它放在一个触发器中。有关此方法的限制,请参阅here。
其他咆哮: