Perché il polling è accettato nella programmazione web?

107

Attualmente sto lavorando a un progetto Ruby on Rails che mostra un elenco di immagini.

Un must per questo progetto è che mostra nuovi post in tempo reale senza la necessità di aggiornare la pagina web. Dopo aver cercato per un po ', mi sono imbattuto in alcune soluzioni e servizi JavaScript come PubNub; tuttavia, nessuna delle soluzioni fornite aveva senso.

Nella soluzione JavaScript ( polling ) accade quanto segue:

  • L'utente 1 visualizza l'elenco delle foto.
  • Sullo sfondo il codice JavaScript sta interrogando un endpoint ogni secondo per vedere se c'è un nuovo post.
  • L'utente 2 aggiunge una nuova foto.
  • C'è un ritardo di 50 ms prima che il nuovo ciclo venga attivato e recuperi i nuovi dati.
  • Il nuovo contenuto viene caricato nel DOM .

Questo sembra strano quando viene tradotto in un esempio reale:

  • L'utente 1 tiene una pila di immagini sulla sua scrivania.
  • Si avvicina al fotografo ogni secondo e chiede se ne ha uno nuovo.
  • Il fotografo crea una nuova foto.
  • Questo secondo quando entra, può scattare la foto e metterla sul mucchio.

Secondo me la soluzione dovrebbe essere la seguente:

  • L'utente 1 tiene una pila di immagini sulla sua scrivania.
  • Il fotografo scatta una nuova foto.
  • Il fotografo raggiunge la pila e la mette con il resto.

La soluzione PubNub è fondamentalmente la stessa, tuttavia questa volta c'è uno stagista che cammina tra le parti per condividere i dati.

Inutile dire che entrambe le soluzioni consumano molta energia in quanto vengono attivate anche quando non ci sono dati da caricare.

Per quanto ne so, non c'è spiegazione (logica) del perché questa modalità di implementazione sia utilizzata in quasi tutte le applicazioni in tempo reale.

    
posta dennis 22.07.2014 - 20:39
fonte

8 risposte

177

Il push funziona bene per 1 o un numero limitato di utenti.

Ora cambia lo scenario con un fotografo e 1000 utenti che vogliono tutti una copia dell'immagine. Il fotografo dovrà camminare fino a 1000 pile. Alcuni di loro potrebbero trovarsi in un ufficio chiuso, o sparsi per tutto il pavimento. O il loro utente in vacanza, e non è interessato a nuove immagini al momento.

Il fotografo sarebbe impegnato a camminare sempre e non a scattare nuove foto.

Fondamentalmente: un modello pull / sond si adatta meglio a molti lettori inaffidabili con requisiti in tempo reale allentati (se un'immagine impiega 10 secondi più tardi per arrivare su una pila, qual è il problema).

Detto questo, un modello push è ancora migliore in molte situazioni. Se hai bisogno di una bassa latenza (hai bisogno di quella nuova foto dopo che è stata scattata), o se gli aggiornamenti sono rari e le richieste frequenti e prevedibili (continua a chiedere al fotografo ogni 10 secondi quando genera una nuova foto al giorno), tirare è inappropriato. Dipende da cosa stai cercando di fare. NASDAQ: push. Servizio meteorologico: pull. Fotografo di matrimoni: probabilmente tira. Agenzia fotografica di notizie: probabilmente push.

    
risposta data 22.07.2014 - 20:57
fonte
106

Sono davvero sorpreso che solo una persona abbia menzionato WebSockets . Il supporto è implementato in praticamente tutti i principali browser .

Infatti PubNub li usa. Per la tua applicazione, il browser probabilmente sottoscriverebbe un socket che trasmetterebbe ogni volta che una nuova foto sarà disponibile. Il socket non invierà la foto, bada bene, ma solo un link in modo che il browser possa scaricarlo in modo asincrono.

Nel tuo esempio immagina qualcosa del tipo:

  1. Gli utenti consentono al fotografo di sapere che desidera conoscere tutte le foto future
  2. Il fotografo dice all'altoparlante che è disponibile una nuova foto
  3. L'utente chiede al fotografo di scattare foto

Questo è un po 'come la tua soluzione di esempio originale. È più efficiente del polling perché il client non deve inviare alcun dato al server (eccetto forse battiti .)

Inoltre, come altri hanno già detto, ci sono altri metodi che sono migliori del semplice polling che funziona nei browser più vecchi ( longpolling, et al .)

    
risposta data 22.07.2014 - 23:51
fonte
41

A volte abbastanza buono è abbastanza buono.

Tra tutti i modi possibili per implementare un processo di comunicazione "in tempo reale", il sondaggio è forse il modo più semplice. Il polling può essere utilizzato efficacemente quando l'intervallo di polling è relativamente lungo (cioè secondi, minuti o ore anziché istantanei) e i cicli di clock consumati controllando la connessione o la risorsa non contano molto.

    
risposta data 22.07.2014 - 20:57
fonte
30

Il protocollo HTTP è limitato dal fatto che il client DEVE essere quello che avvia la richiesta. Il server non può comunicare con il client a meno che non risponda alla richiesta di un cliente.

Quindi, per adattare l'esempio del mondo reale, aggiungi il seguente vincolo:

  • L'utente 2 può SOLO rispondere alle domande dell'Utente 1 con una risposta a frase singola, dopo di che l'Utente 1 deve partire. L'utente 2 non ha altro modo di comunicare.

Con questo nuovo sistema di ritenuta, come faresti diversamente dal polling?

    
risposta data 22.07.2014 - 20:55
fonte
13

Perché il sondaggio è accettato? Perché in realtà ogni soluzione è in realtà un polling di basso livello!

Se il server deve aggiornarti non appena sono disponibili nuove immagini, di solito deve avere una connessione con te - perché gli indirizzi IP cambiano spesso e non sai mai se qualcuno non è più interessato, quindi il cliente deve inviare qualche forma di segnale keep-alive, ad esempio "Sono ancora qui, non sono offline"

Tutte le connessioni stateful (ad esempio, TCP / IP) funzionano allo stesso modo, poiché è possibile inviare solo pacchetti di dati singolari su Internet; non sai mai se l'altra parte è ancora lì.

Quindi ogni protocollo ha un timeout. Se un'entità non risponde entro X secondi, si presume che sia morta. Quindi, anche se si ha solo una connessione aperta tra server e client, senza inviare alcun dato, il server e il client devono inviare pacchetti keep-alive regolari (questo viene gestito a basso livello se si apre una connessione tra loro) - e come viene questo alla fine è diverso dal polling?

Quindi l'approccio migliore sarebbe probabilmente la longpolling:

Il client invia una richiesta immediatamente dopo aver caricato il sito (ad esempio, dicendo al fotografo "Dimmi se ci sono nuove foto"), ma il server non risponde se non ci sono nuove foto. Non appena la richiesta scade, il client chiede di nuovo.

Se il server ora ha nuove immagini, può immediatamente rispondere a tutti i clienti che stanno in fila per nuove immagini. Quindi il tempo di reazione dopo una nuova immagine è ancora più breve rispetto a quello di push, dal momento che il client è ancora in attesa in una connessione aperta per una risposta e non è necessario creare una connessione al client. E le richieste di polling dal client non sono molto più traffico di una connessione costante tra client e server per una risposta!

    
risposta data 24.07.2014 - 11:09
fonte
9

Uno dei vantaggi del polling è che limita il danno che può essere causato se un messaggio scompare o lo stato di qualcosa viene disturbato. Se X chiede a Y il suo stato una volta ogni cinque secondi, allora la perdita di una richiesta o di una risposta comporterà semplicemente che le informazioni di X siano dieci secondi non aggiornate 5. Se Y viene riavviato, X può scoprirlo al prossimo time Y è in grado di rispondere a uno dei messaggi di X. Se X viene riavviato, potrebbe non preoccuparsi di chiedere a Y nulla in seguito, ma chiunque stia osservando lo stato di X dovrebbe riconoscere che è stato riavviato.

Se invece di X il polling Y, X si basava su Y per informarlo ogni volta che il suo stato cambiava, quindi se lo stato di Y cambiava e inviava un messaggio a X, ma per qualsiasi ragione il messaggio non fosse ricevuto, X potrebbe non diventare mai consapevole del cambiamento. Allo stesso modo se Y viene riavviato e non ha mai motivo di inviare a X un messaggio su qualcosa.

In alcuni casi può essere utile per X richiedere che Y invii autonomamente messaggi con il suo stato, sia periodicamente che quando cambia, e solo il polling X se è troppo lungo senza sentire nulla da Y. Tale progetto può eliminare la necessità che X invii la maggior parte dei suoi messaggi (in genere, X dovrebbe almeno occasionalmente informare Y che è ancora interessato a ricevere messaggi, e Y dovrebbe smettere di inviare messaggi se va troppo a lungo senza alcuna indicazione di interesse). Tuttavia, un tale progetto richiederebbe a persistentemente di mantenere le informazioni su X, piuttosto che essere in grado di inviare semplicemente una risposta a chiunque lo abbia interrogato e quindi dimenticare immediatamente chi era. Se Y è un sistema embedded, una tale semplificazione può aiutare a ridurre i requisiti di memoria in modo sufficiente da consentire l'uso di un controller più piccolo ed economico.

Il polling può avere un vantaggio aggiuntivo quando si utilizza un mezzo di comunicazione potenzialmente inaffidabile (ad esempio UDP o radio): può in gran parte eliminare la necessità di riconoscimenti a livello di collegamento. Se X invia a Y una richiesta di stato Q, Y risponde con un rapporto di stato R, e X ascolta R, X non avrà bisogno di sentire alcun tipo di riconoscimento a livello di collegamento per Q per sapere che è stato ricevuto. Viceversa, una volta che Y invia R, non ha bisogno di sapere o preoccuparsi se X lo ha ricevuto. Se X invia una richiesta di stato e non riceve risposta, può inviarne un'altra. Se Y invia un rapporto e X non lo sente, X invierà un'altra richiesta. Se ciascuna richiesta si interrompe una volta e produce una risposta o meno, nessuna delle parti deve sapere o preoccuparsi della ricezione di un particolare messaggio. Dal momento che l'invio di un riconoscimento può consumare quasi la stessa larghezza di banda di una richiesta di stato o di un rapporto, l'utilizzo di un round-trip del rapporto di richiesta non costa molto di più di un rapporto non richiesto e di un riscontro. Se X invia alcune richieste senza ricevere risposte, su alcune reti indirizzate dinamicamente è necessario abilitare i riconoscimenti a livello di collegamento (e chiedere nella stessa richiesta che Y faccia lo stesso) in modo che lo stack del protocollo sottostante possa riconoscere il problema di consegna e cercare una nuova rotta, ma quando le cose funzionano, un modello di report delle richieste sarà più efficiente rispetto all'utilizzo di riconoscimenti a livello di collegamento.

    
risposta data 23.07.2014 - 00:28
fonte
1

La domanda è di bilanciare la quantità di sondaggi non necessari rispetto alla quantità di spinte non necessarie.

Se sondaggi:

  • Hai una risposta in questo preciso momento. Buono se lo chiedi solo occasionalmente o hai bisogno di un set di dati in questo preciso momento.
  • Si potrebbe ottenere una risposta "senza contenuto", causando un carico inutile sulla linea.
  • Metti il carico sulla linea solo quando esegui il polling, ma sempre quando esegui il polling.

Se premi:

  • Fornisci la risposta quando è disponibile, il che consente un'elaborazione immediata dal lato del cliente.
  • Potresti consegnare dati a clienti che non sono interessati a questi dati, causando un carico inutile sulla linea.
  • Metti il carico sulla linea ogni volta che ci sono nuovi dati, ma solo quando ci sono nuovi dati.

Esistono diverse soluzioni su come affrontare i vari scenari e i loro svantaggi, come ad esempio un tempo minimo tra i sondaggi, i proxy di solo polling per togliere il carico dal sistema principale, o - per le spinte - un regolamento per registrare e specificare i dati desiderati seguiti da annullare la registrazione al log-off. Quale che si adatta meglio è nulla che tu possa dire in generale, dipende dal sistema.

Nel tuo esempio il polling non è la soluzione più efficiente, ma la più pratica. È molto facile scrivere un sistema di polling in JavaScript, ed è molto facile implementarlo anche sul lato di consegna. Un server creato per fornire dati di immagine dovrebbe essere in grado di gestire le richieste extra e, in caso contrario, può essere ridimensionato linearmente, poiché i dati sono per lo più statici e possono quindi essere facilmente memorizzati nella cache.

Un metodo push che implementa un log-in, una descrizione dei dati desiderati e infine una disconnessione sarebbe molto efficiente, ma probabilmente è troppo complesso per lo "script-kiddy" medio, e deve affrontare la domanda: che cosa se l'utente spegne il browser e non è possibile eseguire la disconnessione?

Forse è meglio avere più utenti (come l'accesso è facile) che risparmiare qualche dollaro su un altro cache-server?

    
risposta data 23.07.2014 - 15:42
fonte
1

Per qualche ragione, in questi giorni, tutti i più giovani sviluppatori web sembrano aver dimenticato le lezioni del passato e perché alcune cose si sono evolute nel modo in cui hanno fatto.

  1. La larghezza di banda era un problema
  2. La connessione potrebbe essere intermittente.
  3. I browser non avevano la stessa potenza di calcolo
  4. C'erano altri metodi per accedere ai contenuti. Il Web non è w3.

Di fronte a questi vincoli, potresti non avere una comunicazione a 2 vie costante. E se guardaste il modello OSI, troverete che molte considerazioni hanno lo scopo di disaccoppiare la persistenza con la connessione sottostante.

Con questo in mente, un metodo di sondaggio per ottenere informazioni è un ottimo modo per ridurre la larghezza di banda e il calcolo sul lato client. L'aumento del push è in realtà per la maggior parte solo il client che esegue il polling costante o socket web. Personalmente, se fossi lì fuori tutti gli altri, apprezzerei la regolarità dei sondaggi come mezzo di analisi del traffico, in cui una richiesta GET / POST fuori dal tempo segnalerebbe un uomo nella situazione centrale di qualche tipo.

    
risposta data 24.11.2014 - 00:21
fonte

Leggi altre domande sui tag