SoapClient: параллельные асинхронные запросы, реконнект, обработка тайм-аутов
Dklab_SoapClient — это расширенная версия стандартного PHP-класса SoapClient, предназначенная для параллельного (асинхронного) удаленного вызова процедур в высоконагруженных проектах.
При помощи этой библиотеки вы можете, например, строить страницу вашего сайта из блоков, как из конструктора. Каждый блок запрашивается через SOAP отдельно и независимо от других, при этом все запросы происходят параллельно. Если один из блогов не уложился в отведенное ему время (тайм-аут), то его можно не отображать на странице.
По сравнению со встроенным в PHP SoapClient, поддерживаются дополнительные возможности:
- Одновременное, параллельное выполнение запросов к нескольким удаленным процедурам — ключевая особенность библиотеки. Если страница на вашем сайте собирается из 5 удаленных блоков, каждый из которых генерируется по 100ms, их можно запустить параллельно и получить всю страницу целиком не за 500ms, а за те же самые 100ms.
- Реконнект при невозможности установления связи. К сожалению, мир несовершенен, и из-за случайной потери пакетов первая попытка соединения с SOAP-сервером может закончиться тайм-аутом. Это особенно часто происходит, когда проект располагается в нескольких датацентрах. Dklab_SoapClient позволяет задать тайм-аут на время открытия соединения (например, 1 секунду) и, в случае неудачи, повторить попытку указанное число раз. На практике это снижает вероятность итогового сбоя в тысячи раз, т.к. реконнект почти всегда помогает при утере пакета.
- Поддержка тайм-аута на получение данных. Если страница собирается из удаленных блоков, то в случае «подвисания» одного из них «зависает» и вся страница. В то же время, отсутствие одного из блоков при наличии остальных — не такая большая беда. Вы можете указать, сколько времени Dklab_SoapClient должен ждать ответа от удаленной процедуры; если время превышено, возникает исключение PHP, которое вы можете обработать по своему усмотрению, не прерывая загрузку остальных блоков.
class MyServer { public function getComplexData($some) { sleep(1); // типа, эмулируем тяжелый код return array("obj" => (object)array("prop" => $some), "some" => "thing"); } } $soapServer = new SoapServer(null, array('uri' => 'urn:myschema')); $soapServer->setObject(new MyServer()); $soapServer->handle();
А соответствующий ему SOAP-клиент — вот так:
require_once "Dklab/SoapClient.php"; $client = new Dklab_SoapClient(null, array( 'location' => "http://example.com/server.php", 'uri' => 'urn:myschema', 'timeout' => 3, )); // Запросы выполняются параллельно, асинхронно. В сумме - за 1 с. $query1 = $client->async->getComplexData(array("abc")); $query2 = $client->async->getComplexData(array("xyz")); print_r($query1->getResult()); print_r($query2->getResult());
Что важно, при работе с SOAP в PHP сервер может возвращать данные в произвольном формате (например, массив массивов объектов), а клиент — передавать серверу в параметрах переменные любой структуры (к примеру, тот же самый массив массивов объектов). При этом все преобразования выполняются автоматически.
Т.к. Dklab_SoapClient — это расширение встроенного SoapClient, поддерживаются все стандартные возможности последнего, в числе которых:
- Работа с Cookies. Одна процедура может вызвать setcookie(), а другая — прочитать значение этой cooike позже.
- Работа с PHP-сессиями. Одна процедура пишет данные в сессию, вторая — читает.
- Поддержка WSDL-схем и передача сложных бизнес-объектов.
- Обработка исключений, возникающих в удаленной процедуре.
Посмотреть документацию, примеры, автотесты и скачать библиотеку можно здесь: http://dklab.ru/lib/Dklab_SoapClient/
P.S.
Кстати, при разработке используется Git и социальная сеть GitHub. Кто еще их не попробовал, рекомендую это сделать.