La mia comprensione di polling HTTP, polling lungo, streaming HTTP e WebSocket


123

Ho letto molti post su SO e sul web riguardanti le parole chiave nel titolo della mia domanda e ho imparato molto da loro. Alcune delle domande che ho letto sono relative a specifiche sfide di implementazione, mentre altre si concentrano su concetti generali. Voglio solo assicurarmi di aver compreso tutti i concetti e il ragionamento per cui la tecnologia X è stata inventata rispetto alla tecnologia Y e così via. Quindi ecco qui:

Http Polling: fondamentalmente AJAX, utilizzando XmlHttpRequest.

Http Long Polling: AJAX ma il server mantiene la risposta a meno che il server non abbia un aggiornamento, non appena il server ha un aggiornamento, lo invia e quindi il client può inviare un'altra richiesta. Lo svantaggio sono i dati di intestazione aggiuntivi che devono essere inviati avanti e indietro causando un sovraccarico aggiuntivo.

Http Streaming: simile al polling lungo ma il server risponde con un'intestazione con "Transfer Encoding: chunked" e quindi non è necessario avviare una nuova richiesta ogni volta che il server invia alcuni dati (e quindi salvare l'overhead aggiuntivo dell'intestazione). Lo svantaggio qui è che dobbiamo "capire" e capire la struttura dei dati per distinguere tra più blocchi inviati dal server.

Applet Java, Flash, Silverlight: forniscono la possibilità di connettersi a server socket su tcp / ip ma poiché sono plug-in, gli sviluppatori non vogliono dipendere da loro.

WebSocket: sono la nuova API che cerca di affrontare le carenze dei metodi di cui sopra nel modo seguente:

  • L'unico vantaggio di WebSocket rispetto a plug-in come Java Applet, Flash o Silverlight è che i WebSocket sono integrati in modo nativo nei browser e non si basano su plug-in.
  • L'unico vantaggio di WebSocket rispetto allo streaming http è che non è necessario fare uno sforzo per "comprendere" e analizzare i dati ricevuti.
  • L'unico vantaggio di WebSocket rispetto al polling lungo è quello di eliminare le dimensioni extra delle intestazioni e l'apertura e la chiusura della connessione socket su richiesta.

Ci sono altre differenze significative che mi mancano? Mi dispiace se sto ripetendo o combinando molte delle domande già su SO in un'unica domanda, ma voglio solo dare un senso perfetto a tutte le informazioni disponibili su SO e sul web riguardo a questi concetti.

Grazie!


4
Vale anche la pena considerare gli eventi inviati dal server quando non è necessaria la comunicazione bidirezionale.
leggetter

1
Questa è una domanda davvero utile. Penso che potenzialmente sarebbe più utile se ci fosse una risposta a cui più autori potrebbero contribuire.
leggetter

@leggetter Grazie Phil, grazie per il suggerimento sugli eventi inviati dal server. Sono interessato a conoscere gli scenari di comunicazione bidirezionale. Grazie.
Software Guy

1
Con HTTP Streaming e Long-Polling è necessaria una seconda connessione per la comunicazione bidirezionale. Una connessione più lunga per il server -> comunicazione "push" client e una seconda connessione di breve durata per il client -> comunicazioni server. Questa seconda connessione viene utilizzata per eseguire operazioni quali la configurazione e la modifica delle sottoscrizioni ai dati. Quindi, EventSource può essere utilizzato in una soluzione bidirezionale e in effetti è in realtà una soluzione standardizzata nata da HTTP Streaming e Long-Polling.
leggetter

1
Si potrebbe anche voler controllare questa classificazione di tecniche che ho scritto: stackoverflow.com/questions/12078550/...
Alessandro Alinone

Risposte:


92

Ci sono più differenze di quelle che hai identificato.

Duplex / direzionale:

  • Unidirezionale: sondaggio HTTP, sondaggio lungo, streaming.
  • Bi-direzionale: WebSocket, plug-in di rete

In ordine crescente di latenza (approssimativa):

  • WebSockets
  • Plugin di rete
  • Streaming HTTP
  • HTTP a lungo sondaggio
  • Polling HTTP

CORS (supporto cross-origin):

  • WebSocket: sì
  • Plugin di rete: Flash tramite richiesta di criteri (non sono sicuro degli altri)
  • HTTP * (supporto recente)

Dati binari nativi (array tipizzati, BLOB):

  • WebSocket: sì
  • Plugin networking: non con Flash (richiede la codifica URL su ExternalInterface)
  • HTTP *: recente proposta di abilitare il supporto del tipo binario

Larghezza di banda in diminuzione dell'efficienza:

  • Plugin networking: i socket Flash sono grezzi tranne che per la richiesta di policy iniziale
  • WebSocket: handshake di configurazione della connessione e pochi byte per frame
  • Streaming HTTP (riutilizzo della connessione al server)
  • HTTP long-poll: connessione per ogni messaggio
  • Poll HTTP: connessione per ogni messaggio + nessun messaggio di dati

Supporto per dispositivi mobili:

  • WebSocket: iOS 4.2 e versioni successive. Alcuni Android tramite emulazione Flash o utilizzando Firefox per Android o Google Chrome per Android, che forniscono entrambi il supporto WebSocket nativo.
  • Plugin di rete: alcuni Android. Non su iOS
  • HTTP *: principalmente sì

Complessità di utilizzo di Javascript (dal più semplice al più complicato). È vero che le misure di complessità sono in qualche modo soggettive.

  • WebSockets
  • Poll HTTP
  • Plugin di rete
  • HTTP lungo sondaggio, streaming

Si noti inoltre che esiste una proposta W3C per la standardizzazione dello streaming HTTP denominata Eventi inviati dal server . Attualmente è abbastanza presto nella sua evoluzione ed è progettato per fornire un'API Javascript standard con semplicità paragonabile a WebSocket.


1
Grazie mille per la bella risposta Kanaka. Puoi dirmi perché / come lo streaming http ha una latenza maggiore rispetto ai websocket? magari con un semplice esempio? molte grazie.
Software Guy

2
@SoftwareGuy. Molte ragioni. Sui browser recenti, è possibile utilizzare il gestore di eventi XMLHTTPRequest onprogress per ricevere una notifica dei dati. Ma le specifiche dicono che 50 ms è l'intervallo di notifica più piccolo. In caso contrario, è necessario eseguire il polling dei dati di risposta. Inoltre, gli invii del client stabiliscono una nuova connessione HTTP e quindi aumentano notevolmente la latenza di andata e ritorno. Inoltre, molti server Web interrompono le connessioni HTTP dopo circa 30 secondi, il che significa che spesso è necessario continuare a ristabilire la connessione push del server. Ho visto latenze di andata e ritorno WebSocket di 5-10 ms su una rete locale. La latenza dello streaming HTTP sarebbe probabilmente di 50 ms +.
kanaka

Grazie mille per la risposta dettagliata :)
Software Guy

1
@leggetter Grazie Phil, vuoi dire che l'invio di dati dal client al server tramite streaming http causerà un sovraccarico? è possibile inviare dati al server anche tramite streaming http senza aprire una nuova connessione? Grazie.
Software Guy

1
@ Nathan sembra un buon progetto di tesi di laurea magistrale! Certamente, il polling manterrà il sistema più occupato di un modello basato sugli eventi, ma quale potrebbe essere esattamente il risparmio energetico richiederebbe test empirici abbastanza estesi su scale diverse.
kanaka

13

Alcune ottime risposte da altri che coprono un sacco di terreno. Ecco un piccolo extra.

L'unico vantaggio di WebSocket rispetto a plug-in come Java Applet, Flash o Silverlight è che i WebSocket sono integrati in modo nativo nei browser e non si basano su plug-in.

Se con questo intendi che puoi utilizzare Java Applet, Flash o Silverlight per stabilire una connessione socket, allora sì, è possibile. Tuttavia non lo vedi troppo spesso distribuito nel mondo reale a causa delle restrizioni.

Ad esempio, gli intermediari possono chiudere quel traffico e lo fanno. Lo standard WebSocket è stato progettato per essere compatibile con l'infrastruttura HTTP esistente e quindi è molto meno incline a essere interferito da intermediari come firewall e proxy.

Inoltre, WebSocket può utilizzare le porte 80 e 443 senza richiedere porte dedicate, ancora una volta grazie al design del protocollo per essere il più compatibile possibile con l'infrastruttura HTTP esistente.

Queste alternative socket (Java, Flash e Silverlight) sono difficili da utilizzare in modo sicuro in un'architettura cross-origin. Pertanto, le persone che spesso tentano di usarli cross-origin tollereranno le insicurezze piuttosto che sforzarsi di farlo in modo sicuro.

Possono anche richiedere l'apertura di ulteriori porte "non standard" (cosa che gli amministratori non amano fare) o file di criteri che devono essere gestiti.

In breve, l'utilizzo di Java, Flash o Silverlight per la connettività socket è abbastanza problematico da non vederlo distribuito troppo spesso in architetture serie. Flash e Java hanno questa capacità probabilmente da almeno 10 anni, eppure non è prevalente.

Lo standard WebSocket è stato in grado di iniziare con un nuovo approccio, tenendo presenti queste restrizioni e, si spera, avendo imparato alcune lezioni da esse.

Alcune implementazioni di WebSocket utilizzano Flash (o forse Silverlight e / o Java) come fallback quando non è possibile stabilire la connettività WebSocket (ad esempio durante l'esecuzione in un vecchio browser o quando un intermediario interferisce).

Sebbene una sorta di strategia di riserva per queste situazioni sia intelligente, persino necessaria, la maggior parte di coloro che utilizzano Flash e altri soffriranno degli svantaggi descritti sopra. Non deve essere necessariamente così: esistono soluzioni alternative per ottenere connessioni sicure con capacità cross-origin utilizzando Flash, Silverlight, ecc., Ma la maggior parte delle implementazioni non lo farà perché non è facile.

Ad esempio, se ti affidi a WebSocket per una connessione cross-origin, funzionerà correttamente. Ma se poi si esegue in un vecchio browser o un firewall / proxy ha interferito e si fa affidamento su Flash, ad esempio, come fallback, sarà difficile eseguire la stessa connessione cross-origin. A meno che non ti interessi della sicurezza, ovviamente.

Ciò significa che è difficile avere un'unica architettura unificata che funzioni per connessioni native e non native, a meno che tu non sia pronto a dedicare un bel po 'di lavoro o ad andare con un framework che lo ha fatto bene. In un'architettura ideale, non noteresti se le connessioni fossero native o meno; le tue impostazioni di sicurezza funzionerebbero in entrambi i casi; le tue impostazioni di clustering funzionerebbero ancora; la pianificazione della capacità sarebbe ancora valida; e così via.

L'unico vantaggio di WebSocket rispetto allo streaming http è che non è necessario fare uno sforzo per "comprendere" e analizzare i dati ricevuti.

Non è semplice come aprire un flusso HTTP e sedersi mentre i dati scorrono per minuti, ore o più. Clienti diversi si comportano in modo diverso e tu devi gestirlo. Ad esempio, alcuni client eseguiranno il buffering dei dati e non li rilasceranno all'applicazione finché non viene raggiunta una certa soglia. Ancora peggio, alcuni non passeranno i dati all'applicazione fino alla chiusura della connessione.

Quindi, se invii più messaggi al client, è possibile che l'applicazione client non riceva i dati fino a quando non sono stati ricevuti 50 messaggi di dati, ad esempio. Non è troppo in tempo reale.

Sebbene lo streaming HTTP possa essere una valida alternativa quando WebSocket non è disponibile, non è una panacea. Ha bisogno di una buona comprensione per funzionare in modo robusto nelle terre selvagge del Web in condizioni reali.

Ci sono altre differenze significative che mi mancano?

C'è un'altra cosa che nessuno ha ancora menzionato, quindi ne parlerò.

Il protocollo WebSocket è stato progettato per essere un livello di trasporto per protocolli di livello superiore. Sebbene sia possibile inviare messaggi JSON o altro direttamente su una connessione WebSocket, può anche trasportare protocolli standard o personalizzati.

Ad esempio, potresti fare AMQP o XMPP su WebSocket, come hanno già fatto le persone. Quindi un client potrebbe ricevere messaggi da un broker AMQP come se fosse connesso direttamente al broker stesso (e in alcuni casi lo è).

Oppure, se hai un server esistente con un protocollo personalizzato, puoi trasportarlo su WebSocket, estendendo così quel server back-end al Web. Spesso un'applicazione esistente che è stata bloccata nell'azienda può ampliare la sua portata utilizzando WebSocket, senza dover modificare alcuna infrastruttura di back-end.

(Naturalmente, vorresti essere in grado di fare tutto ciò in modo sicuro, quindi controlla con il venditore o il provider WebSocket.)

Alcune persone hanno fatto riferimento a WebSocket come TCP per il Web. Perché proprio come il TCP trasporta protocolli di livello superiore, anche WebSocket fa lo stesso, ma in un modo compatibile con l'infrastruttura Web.

Quindi, sebbene sia sempre possibile inviare messaggi JSON (o qualsiasi altra cosa) direttamente su WebSocket, si dovrebbero anche considerare i protocolli esistenti. Perché per molte cose che vuoi fare, probabilmente c'è un protocollo che è già stato pensato per farlo.

Mi dispiace se sto ripetendo o combinando molte delle domande già su SO in un'unica domanda, ma voglio solo dare un senso perfetto a tutte le informazioni disponibili su SO e sul web riguardo a questi concetti.

Questa è stata un'ottima domanda e le risposte sono state tutte molto istruttive!


Grazie mille Robin per l'eccellente aiuto e informazioni. Se posso chiedere un'altra cosa: mi sono imbattuto in un articolo da qualche parte che dice che lo streaming http può anche essere memorizzato nella cache dai proxy mentre i websocket non lo sono. cosa significa?
Software Guy

Poiché StackOverflow limita la dimensione nei commenti di risposta, ho fornito la mia risposta di seguito: stackoverflow.com/questions/12555043/…
Robin Zimmermann

@RobinZimmermann, la tua risposta è la mia preferita. +1 per la risposta dettagliata davvero buona.
securecurve

10

Se posso chiedere un'altra cosa: mi sono imbattuto in un articolo da qualche parte che dice che lo streaming http può anche essere memorizzato nella cache dai proxy mentre i websocket non lo sono. cosa significa?

(StackOverflow limita la dimensione delle risposte ai commenti, quindi ho dovuto rispondere qui anziché in linea.)

È un buon punto. Per capirlo, pensa a uno scenario HTTP tradizionale ... Immagina che un browser apra una pagina web, quindi richiede http://example.com , diciamo. Il server risponde con HTTP che contiene l'HTML per la pagina. Quindi il browser vede che ci sono risorse nella pagina, quindi inizia a richiedere i file CSS, i file JavaScript e ovviamente le immagini. Sono tutti file statici che saranno gli stessi per tutti i client che li richiedono.

Alcuni proxy memorizzeranno nella cache le risorse statiche in modo che le richieste successive da altri client possano ottenere quelle risorse statiche dal proxy, invece di dover tornare indietro fino al server web centrale per ottenerle. Questa è la memorizzazione nella cache ed è un'ottima strategia per scaricare le richieste e l'elaborazione dai servizi centrali.

Quindi il client n. 1 richiede http://example.com/images/logo.gif , ad esempio. Questa richiesta passa attraverso il proxy fino al server web centrale, che serve logo.gif. Quando logo.gif passa attraverso il proxy, il proxy salverà l'immagine e la assocerà all'indirizzo http://example.com/images/logo.gif .

Quando il client n. 2 arriva e richiede anche http://example.com/images/logo.gif , il proxy può restituire l'immagine e non è richiesta alcuna comunicazione al server web al centro. Ciò fornisce una risposta più rapida all'utente finale, il che è sempre ottimo, ma significa anche che c'è meno carico al centro. Ciò può tradursi in costi hardware ridotti, costi di rete ridotti, ecc. Quindi è una buona cosa.

Il problema sorge quando il logo.gif viene aggiornato sul server web. Il proxy continuerà a fornire la vecchia immagine ignaro della presenza di una nuova immagine. Questo porta a tutto ciò che riguarda la scadenza in modo che il proxy memorizzi nella cache l'immagine solo per un breve periodo prima che "scada" e la richiesta successiva passa attraverso il proxy al server web, che quindi aggiorna la cache del proxy. Esistono anche soluzioni più avanzate in cui un server centrale può eseguire il push in cache note e così via, e le cose possono diventare piuttosto sofisticate.

Come si collega questo alla tua domanda?

Hai chiesto informazioni sullo streaming HTTP in cui il server sta trasmettendo HTTP a un client. Ma lo streaming HTTP è proprio come il normale HTTP, tranne per il fatto che non si smette di inviare dati. Se un server web serve un'immagine, invia HTTP al client che alla fine termina: hai inviato l'intera immagine. E se vuoi inviare dati, è esattamente lo stesso, ma il server invia solo per molto tempo (come se fosse un'immagine enormemente gigantesca, diciamo) o addirittura non finisce mai.

Dal punto di vista del proxy, non è in grado di distinguere tra HTTP per una risorsa statica come un'immagine o dati dallo streaming HTTP. In entrambi i casi, il client ha effettuato una richiesta al server. Il delegato ha ricordato quella richiesta e anche la risposta. La prossima volta che arriva quella richiesta, il proxy fornisce la stessa risposta.

Quindi, se il tuo cliente ha effettuato una richiesta per i prezzi delle azioni, ad esempio, e ha ricevuto una risposta, il prossimo cliente potrebbe fare la stessa richiesta e ottenere i dati memorizzati nella cache. Probabilmente non quello che vuoi! Se richiedi i prezzi delle azioni, vuoi i dati più recenti, giusto?

Quindi è un problema.

Ci sono trucchi e soluzioni alternative per gestire problemi del genere, è vero. Ovviamente puoi far funzionare lo streaming HTTP poiché è in uso oggi. È tutto trasparente per l'utente finale, ma le persone che sviluppano e mantengono quelle architetture devono fare i salti mortali e pagare un prezzo. Si traduce in architetture troppo complicate, il che significa più manutenzione, più hardware, più complessità, più costi. Significa anche che gli sviluppatori spesso devono preoccuparsi di qualcosa che non dovrebbero avere quando dovrebbero concentrarsi solo sull'applicazione, la GUI e la logica di business - non dovrebbero preoccuparsi della comunicazione sottostante.


1
ottimo dettaglio Robin, grazie mille! apprezzo molto la tua risposta completa. Ho già imparato così tanto da tutte le persone fantastiche qui! :)
Software Guy

4

HTTP limita a 2 il numero di connessioni che un client può avere con un server (sebbene ciò possa essere mitigato utilizzando sottodomini) ed è noto che IE lo impone con entusiasmo. Firefox e Chrome ne consentono di più (anche se non ricordo esattamente quanti nella parte superiore della mia testa). Questo potrebbe non sembrare un grosso problema, ma se utilizzi costantemente 1 connessione per gli aggiornamenti in tempo reale, tutte le altre richieste devono subire un collo di bottiglia attraverso l'altra connessione HTTP. E c'è la questione di avere più connessioni aperte dai client che mette più carico sul server.

I WebSocket sono un protocollo basato su TCP e come tali non soffrono di questo limite di connessione a livello HTTP (ma, ovviamente, il supporto del browser non è uniforme).


grazie thejuice, quindi oltre al problema delle connessioni multiple simultanee come evidenziato da te, il resto delle mie ipotesi riguardo ai websocket sono corrette?
Software Guy
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.