Inviare richiesta HTTP da PHP senza attendere la risposta?

Voglio avere una richiesta HTTP GET inviato da PHP. Esempio:

http://tracker.example.com?product_number=5230&price=123.52

L’idea è di fare lato server web-analytics: Invece di inviare il tracking
informazioni da JavaScript a un server, il server invia il tracking
informazioni direttamente a un altro server.

Requisiti:

  • Della richiesta minor tempo possibile, al fine di non
    visibilmente in ritardo di elaborazione della pagina PHP.

  • La risposta dal tracker.example.com non ha bisogno di essere
    controllato. Come esempi, alcune possibili risposte
    tracker.example.com:

    • 200: Che va bene, ma non c’è bisogno di controllare che.

    • 404: sfortuna, ma – di nuovo – non c’è bisogno di controllare che.

    • 301: anche se un redirect sarebbe opportuno, sarebbe di ritardo
      l’elaborazione della pagina PHP, quindi non farlo.

    In breve: Tutti risposte possono essere scartati.

Idee per soluzioni:

  • In un ora cancellato la risposta, qualcuno ha suggerito di chiamare riga di comando
    curl da PHP in un processo di shell. Questa sembra una buona idea,
    solo che non so se il fork di un sacco di shell processi di sotto
    carico pesante è una cosa saggia da fare.

  • Ho trovato php-ga, un pacchetto per fare lato server Google
    Analytics da PHP. Sulla pagina del progetto, è
    citati: “Può essere configurato per […] uso non bloccare le richieste.”
    Finora non ho trovato il tempo per indagare che cosa è il metodo php-ga
    utilizza internamente, ma questo metodo potrebbe essere questo!

In breve: che Cosa è la soluzione migliore per fare generico lato server
di monitoraggio/analisi da PHP.

  • madflow: Perché il tracking non dovrebbe rallentare il tempo di caricamento della pagina. Se il tracker non riesce, poi la sfortuna – ma non c’è bisogno di controllare che ogni volta che.
  • Nota che sto chiedendo un metodo, e non necessariamente per un pacchetto. Per esempio, il metodo php-ga usi per non bloccare le richieste possono essere di interesse anche per soluzioni di tracking che sono – come nel mio caso – non si basa su Google Analytics.
  • C’è stata una risposta che potrebbe essere definito, ma che richiede ulteriori discussioni in merito ai possibili problemi di prestazioni. Purtroppo è stato eliminato. L’idea è stata chiamata a linea di comando curl da PHP. Se c’era un link, credo che possa essere rimosso. curl è parte di standard UNIX server web strumento di catena (curllib è accessibile da PHP, by the way). Inoltre, una volta che trovo il tempo, vorrei guardare in php-ga e indagare il metodo che si utilizza per non bloccare le richieste. Ma forse qualcuno su Stack Overflow sa che questo largo della parte superiore della sua testa?
  • Quindi la domanda diventerebbe troppo specifico, già legato a uno specifico modo di inviare una richiesta al tracker. Solo se assolutamente necessario, voglio un fork di un processo di shell ed eseguire curl in esso. Ma se faccio così, allora il metodo collegate questione potrebbe essere una parte della soluzione.
  • E va bene. modifica la domanda per aggiungere tutti i dettagli pertinenti dai vostri commenti. Speriamo di non ottenere più link-solo risposte.
  • Se avete trovato una soluzione, nel frattempo, sarebbe bello se si potesse postare!
  • non era questa questione si è chiusa? Certo, ci sono un paio di tecniche per la bassa latenza “ping” di pagine, cercherò di dare una risposta entro la fine della giornata.
  • E ‘ stato riaperto. 🙂
  • Mi dispiace per la lunga attesa, fatta di una risposta (non molto orgogliosi del contenuto). Se volete potrei modificare e offrire un po ‘ più di informazioni (magari alcuni esempi di codice). Ho iniziato venerdì sera per fare una risposta, ma ha finito per dare modo a molte informazioni (in una non molto strutturato).
  • Probabilmente utili: segmento.io/blog/come-fare-async-richieste-in-php e Asincrona PHP chiamate?/ (forse il secondo è anche un duplicato? vi aspetto più tardi.)
  • Il segmento.io l’articolo sembra molto interessante, grazie! Nota che non ho bisogno di una risposta, però.
  • Grazie. Ora mi ci è voluto tempo per rispondere, mi dispiace. Ho molto apprezzato la tua risposta. Forse un giorno troverò il tempo per guardare in php-ga e come non bloccando le richieste di ricerca.
  • utilizza stream_set_blocking, ma che riguarda la lettura e la scrittura per il flusso non si “http ping-ing”
  • Ancora interessante. Non sapevo stream_set_blocking‌​. Forse la puoi aggiungere la tua risposta?

InformationsquelleAutor feklee | 2013-01-16



8 Replies
  1. 29

    Purtroppo di PHP, per definizione, è blocco. Mentre questo è vero per la maggior parte delle funzioni e delle operazioni è, di norma, il trattamento, l’attuale scenario è diverso.

    Il processo che io chiamo HTTP-Ping, richiede solo touch un URI specifico, costringendo le specifiche del server di boot-strap è logica interna. Alcune funzioni consentono di realizzare qualcosa di molto simile a questo HTTP-ping, non in attesa di una risposta.

    Prendere nota che il processo di il ping un url, è un processo in due fasi:

    1. Risolvere il DNS
    2. Fare la richiesta

    Mentre si effettua la richiesta deve essere piuttosto veloce una volta che il DNS è stato risolto e il collegamento è fatto, non ci sono molti modi di fare il DNS di risolvere più velocemente.

    Alcuni modi di fare un http-ping sono:

    1. cURL, impostando CONNECTION_TIMEOUT un valore basso,
    2. fsockopen chiudendo subito dopo la scrittura
    3. stream_socket_client (come fsockopen) e anche l’aggiunta di STREAM_CLIENT_ASYNC_CONNECT

    Mentre entrambi cURL e fsockopen sono sia il blocco, mentre il DNS è stato risolto. Ho notato che fsockopen è significativamente più veloce, anche in scenari peggiori.

    stream_socket_client invece dovrebbe risolvere il problema dei DNS resolving e dovrebbe essere la soluzione ottimale in questo scenario, ma non sono ancora riuscito a farlo funzionare.

    Una soluzione finale è quello di iniziare un altro thread/processo che fa per voi. Effettuare una chiamata di sistema per questo dovrebbe funzionare, ma anche forking l’attuale processo dovrebbe farlo anche. Purtroppo entrambi non sono davvero sicuro in applicazioni in cui non è possibile controllare l’ambiente in cui gira il PHP.

    Chiamate di sistema sono più spesso di quanto non sia bloccato e pcntl non è abilitata per impostazione predefinita.

    • In realtà, avrei potuto evitare di DNS cercare specificando un indirizzo IP. È solo che non si verifica a me ancora.
    • volevo ricordare che in post, ma verso la fine stavo già chiedendo che cosa i diritti di accesso di cui si dispone sul server. Attenzione per le modifiche DNS però!
    • Non posso capire pienamente dei diritti di accesso hanno a che fare con la specificazione di un IP (diverso da quello che ho potuto specificare anche in /etc/hosts), ma ho tutti i diritti di accesso (root). In ogni caso, una risposta generica, ovviamente, suite di Overflow dello Stack migliore.
    • Khez devo dire che è una bella soluzione. Si può anche avere il potenziale per molto di base asincronia in php senza plugin
    • beh, async è già parte dell’hack spec e non sarei sorpreso se il PHP 7.x pickup… ma sono contento che hai trovato la soluzione “bello” 😀
  2. 14

    Direi tracker.example.com in questo modo:

    get_headers('http://tracker.example.com?product_number=5230&price=123.52');

    e nel tracker script:

    ob_end_clean();
    ignore_user_abort(true);
    ob_start();
    header("Connection: close");
    header("Content-Length: " . ob_get_length());
    ob_end_flush();
    flush();
    
    //from here the response has been sent. you can now wait as long as you want and do some tracking stuff 
    
    sleep(5); //wait 5 seconds
    do_some_stuff();
    exit;
    • Grazie! Che sembra un buon approccio.
    • ignore_user_abort() necessita di un valore (vero), altrimenti restituisce solo il valore corrente.
    • funziona benissimo sul mio locale wamp server, ma non sul mio server. penso che il mio server ha bisogno di configurazione
  3. 11

    Ho implementato la funzione per fast GET richiesta di url senza attendere risposta:

    function fast_request($url)
    {
        $parts=parse_url($url);
        $fp = fsockopen($parts['host'],isset($parts['port'])?$parts['port']:80,$errno, $errstr, 30);
        $out = "GET ".$parts['path']." HTTP/1.1\r\n";
        $out.= "Host: ".$parts['host']."\r\n";
        $out.= "Content-Length: 0"."\r\n";
        $out.= "Connection: Close\r\n\r\n";
    
        fwrite($fp, $out);
        fclose($fp);
    }
  4. 3

    È possibile utilizzare shell_exec, e la riga di comando curl.

    Per un esempio, vedere questa domanda

    • Questo appare come una soluzione decente. Solo mi chiedo se potrebbe essere problematico per deporre le uova un sacco di shell processi quando molti utenti stanno accedendo alla pagina.
    • Puoi carne questa risposta un po’? (vedere le modifiche apportate alla domanda)
  5. 1

    Venuto qui, mentre la ricerca di un problema simile. Se si dispone di una connessione a un database utile, un’altra possibilità è rapidamente roba i dettagli della richiesta in una tabella, e quindi hanno compilato il cron processo che esamina periodicamente la tabella per il nuovo record di processo, e rende la richiesta di tracking, liberando la vostra applicazione web da dover fare la richiesta HTTP stessa.

    • In realtà, l’app in questione, c’è qualcosa di simile. Non Cron, tuttavia (cerco di evitare di Cron). Si tratta di un demone che scarica da Url leggere da un database, in un ciclo infinito. Per il caso di utilizzo, anche se, utilizzando il demone e il database associato si sente come eccessivo.
  6. 0
    <?php
    //Create a stream
    $opts = array(
      'http'=>array(
        'method'=>"GET",
        'header'=>"Accept-language: en" 
      )
    );
    
     $context = stream_context_create($opts);
    
    //Open the file using the HTTP headers set above
    $file = file_get_contents('http://tracker.example.com?product_number=5230&price=123.52', false, $context);
    ?>
    • Forse offrire una spiegazione per quanto il tuo codice funziona e perché esso soddisfi i bisogni dell’interlocutore?
    • Sono abbastanza sicuro che questo farà tutta la richiesta e attendere una risposta prima di procedere, non è vero ?
  7. 0

    Avevo bisogno di fare qualcosa di simile, basta eseguire il ping di un url e scartare tutte le risposte. Ho usato il proc_open di comando che consente di terminare il processo subito con proc_close. Sto assumendo che tu abbia lynx installato sul server:

    <?php    
    function ping($url) {
          $proc = proc_open("lynx $url",[],$pipes);
          proc_close($proc);
        }
    ?>
  8. -1

    Si può effettivamente fare questo utilizzando CURL direttamente.

    Ho implementato utilizzando un breve timeout (CURLOPT_TIMEOUT_MS) e/o l’utilizzo di curl_multi_exec.

    Essere informati: alla fine ho abbandonato questo metodo perché non ogni richiesta è stata effettuata correttamente. Questo potrebbe essere stato causato da un mio server se non sono stato in grado di escludere la possibilità di curl per mancanza di.

    • Non è probabile che le richieste non riuscita perché, di fatto, una connessione deve essere stabilita prima di inviare la richiesta? AFAICS, per il problema a portata di mano, non è saggio per impostare CURLOPT_TIMEOUT_MS per un bassissimo valore.

Lascia un commento