2015-07-17 10 views
5

Il mio obiettivo è utilizzare vari servizi Web e quindi unire i risultati.Consumo di servizi Web SOAP e REST allo stesso tempo in PHP

Lo stavo usando PHP cURL, ma con l'aumento del numero di servizi Web, il mio servizio ha rallentato poiché il processo era in attesa di una risposta e quindi ha effettuato la richiesta al servizio Web successivo.

Ho risolto questo problema utilizzando curl_multi e tutto funzionava correttamente.

Ora, ho un nuovo problema, perché ho nuovi servizi Web da aggiungere nel mio servizio che usano Soap Protocol e non posso più fare richieste simultanee, perché non uso cURL per i servizi Web Soap, io uso SoapClient.

So che posso creare l'XML con le direttive soap e quindi inviarlo con cURL, ma questa mi sembra una cattiva pratica.

In breve, esiste un modo per utilizzare contemporaneamente i servizi Web REST e SOAP?

risposta

5

Desidero in primo luogo provare un unificato, asincrono guzzle configurazione come altri hanno detto. Se ciò non funziona, suggerisco di non utilizzando il processo di forking o multithreading. Né sono semplici da usare o da mantenere. Ad esempio, mixing guzzle and threads richiede particolare attenzione.

Non conosco la struttura dell'applicazione, ma questo potrebbe essere un buon caso per una coda.Metti un messaggio in coda per ogni chiamata API e lascia che più PHP daemons legga la coda e faccia le richieste effettive. Il codice può essere organizzato su usando curl o SoapClient a seconda del protocollo o dell'endpoint invece di provare a combinarli. È sufficiente avviare quanti demoni desideri rendere le richieste in parallelo. Ciò evita tutta la complessità del threading o della gestione dei processi e scala facilmente.

Quando utilizzo questa architettura, tengo anche traccia di un "semaforo" in un archivio di valori-chiave o in un database. Avvia il semaforo con un conteggio delle chiamate API da effettuare. A mano a mano che ciascuno è completo, il conteggio viene ridotto. Ogni processo verifica quando il conteggio raggiunge lo zero e quindi sai che tutto il lavoro è stato eseguito. Questo è veramente necessario quando c'è un'attività successiva, come il calcolo di qualcosa da tutti i risultati dell'API o l'aggiornamento di un record per far sapere agli utenti che il lavoro è stato eseguito.

Ora questa configurazione sembra più complicata del processo di biforcazione o multithreading, ma ogni componente è facilmente controllabile e scalabile tra i server.

Ho creato uno PHP library che consente di creare l'architettura che sto descrivendo. È un pipelining di base che consente un mix di processi sincroni e asincroni. Il lavoro asincrono è gestito da una coda e un semaforo. Le chiamate API che devono succedere in sequenza ottengono ciascuna una classe Process. Chiamate API che potrebbero essere eseguite contemporaneamente in una classe MultiProcess. A ProcessList imposta la pipeline.

1

non è qualcosa di buono su php, e puoi facilmente trovare bug di crash edge-case facendolo, ma php PUO 'fare multithreading - controlla php pthreads e pcntl_fork. (nessuno dei quali funziona su un server web dietro php-fpm/mod_php, btw e pcntl_fork funziona solo su sistemi unix (linux/bsd), windows non funzionerà)

tuttavia, probabilmente starai meglio con passaggio a un processo principale -> modello dei processi di lavoro con proc_open & co. questo funziona dietro i server web sia in php-fpm che in mod_php e non dipende dal fatto che pthreads sia installato e funzioni anche su Windows, e non danneggerà gli altri worker se un singolo worker si blocca. puoi anche utilizzare l'interfaccia curl_multi di php (che è molto ingombrante per essere corretta) e continuare a utilizzare le semplici funzioni di curl_exec &. (Ecco un esempio per l'esecuzione di più istanze di pinghttps://gist.github.com/divinity76/f5e57b0f3d8131d5e884edda6e6506d7 - ma io sto suggerendo usando php cli per questo, ad esempio proc_open('php workerProcess.php',...);, ho fatto diverse volte prima con successo.)

2

Sì, è possibile.

Utilizzare un client HTTP (ad esempio: guzzle, httpful) la maggior parte di questi sta seguendo PSR7, prima che si abbia un contratto. La cosa più importante è che hanno un sacco di plugin per SOAP e REST.

EX: se si sceglie guzzle come client HTTP ha i plugin SOAP. Sapete che REST è tutto basato sulla chiamata di un servizio in modo da non aver bisogno di un pacchetto extra per questo, basta usare lo stesso guzzle.

** scrivere le chiamate API in modo asincrono (non bloccante) che aumenterà le prestazioni. Una soluzione è possibile utilizzare promises

Read more

0

Si potrebbe eseguire un cronjob.php con crontab e avviare altri script php in modo asincrono:

// cronjob.php 
$files = [ 
    'soap-client-1.php', 
    'soap-client-2.php', 
    'soap-client-2.php', 
]; 

foreach($files as $file) { 
    $cmd = sprintf('/usr/bin/php -f "%s" >> /dev/null &', $file); 
    system($cmd); 
} 

sapone-client-1.php

$client = new SoapClient('http://www.webservicex.net/geoipservice.asmx?WSDL'); 

$parameters = array(
    'IPAddress' => '8.8.8.8', 
); 
$result = $client->GetGeoIP($parameters); 
// @todo Save result 

Ogni script php inizia una nuova richiesta SOAP, memorizza il risultato nel database. Ora è possibile elaborare i dati leggendo il risultato dal database.

0

Questo sembra un problema di architettura. Dovresti invece consumare ogni servizio con un file/URL separato e scartare JSON da quelli in un front-end HTML5/JS. In questo modo, il tuo servizio può essere diviso in molti blocchi asincroni e la velocità di ciascuno può essere modificata separatamente.

Problemi correlati