PHP中的异步Web服务

时间:2015-07-19 05:34:53

标签: php web-services asynchronous

我从某些Web服务获取信息,但我希望我所调用的方法只是异步,因为请求花费的时间太长,导致网站加载缓慢。

我目前正在使用普通的SOAP调用

$client = new SoapClient("http://xxxx.com/webservices/json.asmx?WSDL");

$result = $client->__soapCall($id, $parameters);

有人可以帮助我吗

4 个答案:

答案 0 :(得分:1)

这种方法通常不是服务器端的异步策略,因为这不符合php的工作方式。而是采用这种策略:

您处理请求并将html页面响应给具有容器元素的客户端,其中缓慢的API调用的结果将转移到该客户端。但容器是空的或包含占位符。此外,还提供了一个客户端逻辑,即javascript,它将处理程序注册到客户端的文档就绪事件。在该处理程序内部,它将ajax请求返回给服务器,通常每个API调用必须执行一个请求。在ajax请求中接收的有效负载用于使用最终数据填充html内的容器。

这样,页面/视图本身的生成和呈现与完全等待API调用分离。此外,该策略是透明的,用户可以看到提取的附加数据使得等待时间从心理学的角度来看更容易接受。

您可以想到该策略的一种变体,它已经注册了基于服务器的作业,执行实际的API调用并缓冲结果。这样你就可以保持往返发送页面并等待ajax调用进入的延迟缓慢。但是这里的挑战是保持这些作业与原始请求之间的连接以及随后的ajax调用一个简单的任务。通常,该优点根本不能证明额外的努力。

因此,作为一个底线,可以说通常没有实现纯php中的异步策略。相反,原始请求被分成几个单独的请求。只处理第一个请求并立即响应,与任何慢速API调用无关。然后,并行地,ajax请求触发API调用并将结果信息添加到对第一个请求的响应中。

答案 1 :(得分:1)

3年后,我认为人们开始意识到“异步”并不意味着“多线程”。以NodeJS为例-它几乎与PHP具有相同的单线程功能,但也具有强大的异步功能。而且,PHP也具有此功能,如果您知道要查找的位置(当然,可以更好地开发它)

其基础是Curl library,其中包括不起眼的 [Display(Name="E-mail")] [Required(ErrorMessage = "Введите E-mail")] [EmailAddress(ErrorMessage ="The Email field is not a valid e-mail address.")] public string Email { get; set; } 函数。这样,您可以并行触发多个HTTP请求,并在它们进入时处理响应,或者等待所有响应完成,等等。所有这一切都发生在单个线程上,完全异步。您可以定期轮询状态(占用一些CPU资源),也可以使用curl_multi_select()来实际挂起线程(例如sleep()),直到发生一些活动为止。所有的魔术都发生在OS内核本身中,这意味着它会尽可能地高效。

那么您如何使它与SOAP一起使用?事实证明,您可以继承SoapClient类并重写__doRequest()方法。可能还有很多其他方法。而且,您有一个异步SOAP客户端!

这需要一些工作,Curl可能很难正确使用,因此您可能要使用其他人已经编写的代码。 Guzzle是一个不错的库,它将Curl包装在一个更易于使用的包装器中。或者,如果您搜索“ php异步soap客户端”,则可以获得几个库,人们已经在其中完成了所有艰苦的工作,并且您可以采用现成的异步curl_multi_*派生类。例如,Google上的前几个结果给了我ReactPHP-SoapPHP-Parallel-SoapAsync-Soap-Guzzle。我认为所有这些都可以作为Composer软件包使用。

答案 2 :(得分:0)

异步 ​​- 它不是关于php的。 脚本按原样工作,一行一行,我们在这里什么都不做。 如果你想快速做事(更接近异步),你应该重新制作应用程序架构。

https://en.wikipedia.org/wiki/Service-oriented_architecture

起初你应该有一些"巴士"事件中,一个脚本放置一些命令,其他脚本(恶魔)监听并执行此命令。

这里的利润是将一些命令推送到总线要快得多(我们甚至不需要等待响应)然后做实际的工作。实际工作($ client = new SoapClient(...)在这里应该由其他脚本完成。

抱歉英语

答案 3 :(得分:0)

这还取决于您是否需要来自Web服务的输出。

如果您需要,请使用Ajax方式或服务方式。您还可以使用队列来管理作业,例如Redis或beanstalkd。

如果您不需要输出,只想调用api,那么您也可以将该代码放在另一个脚本中,并在后台调用它,如

shell_exec('php script.php someargs >/dev/null 2>&1 &');

注意重定向,需要它们。