Perché usare AJAX quando WebSocket è disponibile?


203

Sto usando WebSocket da un po 'di tempo, ho scelto di creare uno strumento di gestione dei progetti Agile per il mio progetto dell'ultimo anno all'università utilizzando Node server e WebSocket. Ho scoperto che l'utilizzo di WebSocket ha fornito un aumento del 624% del numero di richieste al secondo che la mia applicazione potrebbe elaborare.

Tuttavia da quando ho iniziato il progetto ho letto delle lacune di sicurezza e alcuni browser hanno scelto di disabilitare WebSocket per impostazione predefinita.

Questo mi porta alla domanda:

Perché usare AJAX quando WebSocket sembra fare un ottimo lavoro nel ridurre la latenza e il sovraccarico di risorse, c'è qualcosa che AJAX fa meglio di WebSocket?


2
Ecco un elenco di motori che supportano i socket Web. en.wikipedia.org/wiki/…
Dante

Risposte:


209

WebSocket non è destinato a sostituire AJAX e non è nemmeno un sostituto della cometa / sondaggio lungo (anche se ci sono molti casi in cui ciò ha senso).

Lo scopo di WebSocket è fornire una connessione a bassa latenza, bidirezionale, full duplex e di lunga durata tra un browser e un server. WebSocket apre nuovi domini applicativi alle applicazioni browser che non erano realmente possibili utilizzando HTTP e AJAX (giochi interattivi, flussi multimediali dinamici, collegamento ai protocolli di rete esistenti, ecc.).

Tuttavia, esiste sicuramente una sovrapposizione di intenti tra WebSocket e AJAX / Comet. Ad esempio, quando il browser vuole essere informato degli eventi del server (cioè push), le tecniche Comet e WebSocket sono certamente entrambe opzioni praticabili. Se l'applicazione richiede eventi push a bassa latenza, questo sarebbe un fattore a favore di WebSocket. D'altra parte, se è necessario coesistere con i framework esistenti e le tecnologie distribuite (OAuth, API RESTful, proxy, bilanciamento del carico), questo sarebbe un fattore a favore delle tecniche delle comete (per ora).

Se non hai bisogno dei vantaggi specifici offerti da WebSocket, probabilmente è un'idea migliore attenersi a tecniche esistenti come AJAX e Comet perché ciò ti consente di riutilizzare e integrare un enorme ecosistema esistente di strumenti, tecnologie, meccanismi di sicurezza , basi di conoscenza (ovvero molte più persone su StackOverflow conoscono HTTP / Ajax / Comet rispetto a WebSocket), ecc.

D'altra parte, se stai creando una nuova applicazione che non funziona bene con i limiti di latenza e connessione di HTTP / Ajax / Comet, allora considera l'utilizzo di WebSocket.

Inoltre, alcune risposte indicano che uno degli svantaggi di WebSocket è il supporto limitato / misto di server e browser. Vorrei solo diffonderlo un po '. Mentre iOS (iPhone, iPad) supporta ancora il protocollo precedente (Hixie), la maggior parte dei server WebSocket supporta sia Hixie che HyBi / IETF 6455 . La maggior parte delle altre piattaforme (se non hanno già il supporto integrato) può ottenere il supporto WebSocket tramite web-socket-js (polyfill basato su Flash). Questo copre la stragrande maggioranza degli utenti web. Inoltre, se si utilizza Nodo per il back-end del server, prendere in considerazione l'utilizzo di Socket.IO che include web-socket-js come fallback e se anche quello non è disponibile (o disabilitato), si tornerà a utilizzare qualsiasi tecnica Comet sia disponibile per il browser specificato.

Aggiornare : iOS 6 ora supporta l'attuale standard HyBi / IETF 6455.


37
E ora all'alba del 2014, WebSocket è praticamente uno standard (RFC 6455) e solo Opera mini non lo supporta.
Dirk Bester,

4
È vero, Opera Mini non lo supporta, ma più imbarazzante è la mancanza di supporto del browser Android che rende un po 'più complesso da usare con le app basate su webview (Cordova PhoneGap)
Miles M.

2
@kanaka, Se entrambi fanno ugualmente bene file di grandi dimensioni, perché non semplicemente inviare tutto tramite websocket? Perché preoccuparsi di ajaxare pagine / dati quando tutto può essere inviato tramite WebSocket? (Supponiamo che sia già il 2020 e tutti i browser hanno il supporto per WebSocket)
Pacerier

3
@Pacerier una risposta completa sarebbe lunga, ma sostanzialmente si riduce al fatto che stai cercando di reimplementare cose che il browser fa già bene (cache, sicurezza, parallelismo, gestione degli errori, ecc.). Per quanto riguarda le prestazioni, sebbene la velocità di trasferimento di file di grandi dimensioni da zero sia simile da zero, i browser hanno avuto anni per ottimizzare la memorizzazione nella cache dei contenuti Web (molti dei quali si applicano alle richieste AJAX), quindi in pratica è improbabile che il passaggio da AJAX a WebSocket fornisca molto vantaggio per la funzionalità esistente. Ma per la comunicazione bidirezionale a bassa latenza è una vittoria enorme.
Kanaka,

5
Mi dispiace ma per me non risponde alla domanda. Fondamentalmente dice solo che non sono pensati per sostituirsi a vicenda e che WS non è completamente supportato (è ora). Non risponde perché preferiresti AJAX al websocket? Prendiamo ad esempio Discord. Discord utilizza WS per inviare messaggi ed eventi dal server ai client, nel frattempo utilizza le richieste HTTP dal client al server (invia messaggio, richiedi dati, ecc.). Sono arrivato a questa domanda per ottenere effettivamente una risposta sul motivo per cui l'avresti fatto. C'è una qualche ragione tecnica per cui dovresti mettere AJAX sopra la connessione WS aperta?
Charlotte Dunois,

63

Avanti veloce fino a dicembre 2017, i Websocket sono supportati da (praticamente) tutti i browser e il loro utilizzo è molto comune.

Tuttavia, ciò non significa che Websocket sia riuscito a sostituire AJAX, almeno non completamente, soprattutto perché l'adattamento HTTP / 2 è in aumento.

La risposta breve è che AJAX è ancora eccezionale per la maggior parte delle applicazioni REST, anche quando si utilizzano Websocket. Ma dio è nei dettagli, quindi ...:

AJAX per il polling?

L'uso di AJAX per il polling (o polling lungo) sta scomparendo (e dovrebbe esserlo), ma rimane ancora in uso per due buoni motivi (principalmente per le app Web più piccole):

  1. Per molti sviluppatori, AJAX è più facile da programmare, specialmente quando si tratta di codificare e progettare il backend.

  2. Con HTTP / 2, il costo più elevato relativo ad AJAX (creazione di una nuova connessione) è stato eliminato, consentendo alle chiamate AJAX di essere abbastanza performanti, in particolare per la pubblicazione e il caricamento di dati.

Tuttavia, il push di Websocket è di gran lunga superiore ad AJAX (non è necessario riautenticare o inviare nuovamente le intestazioni, non è necessario il round trip "nessun dato", ecc.). Questo è stato discusso diverse volte.

AJAX per REST?

Un migliore utilizzo di AJAX sono le chiamate API REST. Questo utilizzo semplifica la base di codice e impedisce il blocco della connessione Websocket (soprattutto su upload di dati di medie dimensioni).

Esistono diversi motivi convincenti per preferire AJAX per le chiamate API REST e i caricamenti di dati:

  1. L'API AJAX è stata praticamente progettata per le chiamate all'API REST ed è perfetta.

  2. Le chiamate REST e i caricamenti con AJAX sono notevolmente più facili da codificare, sia sul client che sul back-end.

  3. All'aumentare del payload dei dati, le connessioni Websocket potrebbero essere bloccate a meno che non sia codificata la logica di frammentazione / multiplex dei messaggi.

    Se un caricamento viene eseguito in una singola sendchiamata Websocket , potrebbe bloccare un flusso Websocket fino al termine del caricamento. Ciò ridurrà le prestazioni, soprattutto su client più lenti.

Un design comune utilizza piccoli messaggi bidi trasferiti su Websocket mentre REST e upload di dati (da client a server) sfruttano la facilità d'uso di AJAX per impedire il blocco di Websocket.

Tuttavia, su progetti più grandi, la flessibilità offerta da Websocket e l'equilibrio tra la complessità del codice e la gestione delle risorse farà da bilancia a favore di Websocket.

Ad esempio, i caricamenti basati su Websocket potrebbero offrire la possibilità di riprendere i caricamenti di grandi dimensioni dopo che una connessione viene interrotta e ristabilita (ricordi quel film da 5 GB che volevi caricare?).

Codificando la logica di frammentazione del caricamento, è facile riprendere un caricamento interrotto (la parte difficile stava codificando la cosa).

Che dire di HTTP / 2 push?

Dovrei probabilmente aggiungere che la funzione push HTTP / 2 non (e probabilmente non può) sostituire Websocket.

Questo era stato discusso qui precedenza, ma basti ricordare che una singola connessione HTTP / 2 serve l'intero browser (tutte le schede / finestre), quindi i dati inviati da HTTP / 2 non sanno a quale scheda / finestra appartiene, eliminando la sua capacità di sostituire la capacità di Websocket di inviare i dati direttamente a una specifica scheda / finestra del browser.

Mentre i websocket sono ottimi per la comunicazione di dati bidirezionali di piccole dimensioni, AJAX ha comunque apportato numerosi vantaggi, soprattutto se si considerano payload più grandi (upload, ecc.).

E sicurezza?

Bene, generalmente, maggiore è la fiducia e il controllo offerti a un programmatore, più potente è lo strumento ... e maggiori sono i problemi di sicurezza che si insinuano.

AJAX per natura avrebbe il sopravvento, poiché la sua sicurezza è integrata nel codice del browser (che a volte è discutibile, ma è ancora lì).

D'altra parte, le chiamate AJAX sono più suscettibili agli attacchi "man in the middle", mentre i problemi di sicurezza di Websocket sono di solito bug nel codice dell'applicazione che ha introdotto un difetto di sicurezza (di solito la logica di autenticazione back-end è dove li troverai).

Personalmente non trovo che questa sia una grande differenza, se non altro credo che i Websocket siano leggermente migliori, specialmente quando sai cosa stai facendo.

La mia modesta opinione

IMHO, userei Websocket per tutto tranne le chiamate API REST. Caricamenti di big data Vorrei frammentare e inviare su Websocket quando possibile.

Il polling, IMHO, dovrebbe essere messo fuorilegge, il costo nel traffico di rete è orribile e la spinta di Websocket è abbastanza facile da gestire anche per i nuovi sviluppatori.


2
Piccolo errore grammaticale "se non altro" ... pensa 😀
spottedmahn,

2
@spottedmahn - Grazie! Immagino sia quello che succede, uso il mio editor di codice per redigere il testo My
Myst,

1
Mi scuso, ero assente alla scadenza della taglia. Cattiva pianificazione da parte mia. Ho creato un altro premio che ti assegnerò dopo la scadenza delle 23 ore.
Duncan Jones,

@Myst grazie per questa grande spiegazione. Cosa preferiresti per le notifiche live come fb / stackoverflow? Sto progettando un servizio web RestFull per la mia applicazione Web, ma molto confuso cosa dovrei usare per la funzione di notifica? AJAX o WebSocket?
TheCoder

Le notifiche @puspen sono (IMHO) ideali per Websocket. Ci sono molte decisioni da prendere quando si progettano la logica di riconnessione e le code di notifica offline, ma la notifica effettiva è sia facile da codificare che performante con i websocket.
Myst,

18

Oltre ai problemi con i browser più vecchi (incluso IE9, poiché WebSocket sarà supportato a partire da IE10), ci sono ancora grossi problemi con gli intermediari di rete che non supportano ancora WebSocket, inclusi proxy trasparenti, proxy inversi e bilanciamento del carico. Esistono alcuni gestori di telefonia mobile che bloccano completamente il traffico WebSocket (ovvero dopo il comando UPGRADE HTTP).

Con il passare degli anni, WebSocket sarà sempre più supportato, ma nel frattempo dovresti sempre disporre di un metodo di fallback basato su HTTP per l'invio di dati ai browser.


Fortunatamente la maggior parte dei framework WebSocket supporta detti fallback, incluso l'uso di Flash per socket. Socketn.IO e SignalR sono entrambi framework decenti ... anche se sei davvero limitato, come dici a causa di proxy e bilanciamento del carico. Fortunatamente, sia Node.JS che il prossimo IIS svolgono un lavoro decente con questo ruolo.
Tracker 1

Curioso: quali operatori bloccano WebSocket sulla porta 80? Quale blocco WebSocket sicuro (WSS) sulla porta 443? Quest'ultimo implica proxy Web MITM forzati e trasparenti ... mai visto nelle reti pubbliche (solo quelle aziendali), poiché richiede l'installazione di nuovi certificati CA nei browser.
oberstet

Ad esempio, al momento Vodafone Italia blocca WS sulla porta 80, ma consente WSS sulla porta 443. Puoi testare qualsiasi operatore abbastanza facilmente tramite la nostra home page, a cui puoi accedere sia in HTTP che HTTPS. Prova WebSocket e torna a HTTP se sono bloccati. Utilizzare questo URL per visualizzare un widget nel mezzo che riporta il trasporto corrente: lightstreamer.com/?s
Alessandro Alinone

17

La maggior parte delle lamentele che ho letto su WebSocket e la sicurezza provengono da fornitori di sicurezza di strumenti di sicurezza del browser Web e firewall. Il problema è che non sanno come eseguire l'analisi della sicurezza del traffico dei websocket, perché una volta effettuato l'aggiornamento da HTTP al protocollo binario del websocket, il contenuto del pacchetto e il suo significato sono specifici dell'applicazione (in base a qualunque programma). Questo è ovviamente un incubo logistico per queste aziende il cui sostentamento si basa sull'analisi e sulla classificazione di tutto il traffico Internet. :)


11

I WebSocket non funzionano nei browser Web meno recenti e quelli che lo supportano spesso hanno implementazioni diverse. Questo è praticamente l'unico buon motivo per cui non vengono utilizzati sempre al posto di AJAX.


8
Un motivo migliore è che una richiesta AJAX è una normale richiesta HTTP, il che significa che può recuperare risorse HTTP; WebSocket non può farlo.
Dan

@Dan Cosa succede se, ad esempio, i file di immagine vengono inviati come base64, CSS come testo, JavaScript anche come testo e quindi aggiunti al documento? Sarebbe plausibile?
Jack

@DanD. +1, sono d'accordo, suppongo che mi stavo avvicinando maggiormente alla domanda dal contesto dello streaming rapido dei dati come nell'esempio della domanda, ma questo è sicuramente corretto.
jli

@Dan D - a volte non vuoi che tutta quella merda vada oltre la linea, come i biscotti e le intestazioni ...
vsync,

8
@DanD., HTTP e WebSocket sono due protocolli distinti, ovviamente non possiamo richiedere risorse HTTP utilizzando il protocollo WebSocket per lo stesso motivo per cui non possiamo richiedere risorse WebSocket utilizzando il protocollo HTTP! Ciò non significa che il client non possa richiedere file html e / o di immagine inviati tramite il protocollo Websocket.
Pacerier,

2

Non penso che possiamo fare un chiaro confronto tra Websocket e HTTP in quanto non sono rivali né risolvono gli stessi problemi.

I websocket sono un'ottima scelta per gestire lo streaming di dati bidirezionali di lunga durata in modo quasi in tempo reale, mentre REST è ottimo per comunicazioni occasionali. L'uso di websocket è un investimento considerevole, quindi è eccessivo per connessioni occasionali.

È possibile che Websocket funzioni meglio in presenza di carichi elevati, in alcuni casi HTTP è leggermente più veloce perché può utilizzare la memorizzazione nella cache. Confrontare REST con Websocket è come confrontare le mele con le arance.

Dovremmo verificare quale fornisce la soluzione migliore per la nostra applicazione, quale si adatta meglio alle vincite del nostro caso d'uso.


1
la domanda riguardava AJAX in generale, non REST in particolare. È vero che AJAX può essere usato per REST, ma è anche usato per polling e polling lungo. Anche se sono d'accordo con la tua conclusione (come puoi dire dalla mia risposta), penso che la tua risposta potrebbe riflettere la distinzione (nota che Websocket può essere usato anche per REST, anche se non usando i metodi HTTP).
Myst,

@Myst Sono d'accordo con te.
Gaurav Gandhi,

1

Un esempio delle differenze tra HTTP e Websocket sotto forma di una lib di dimensioni client in grado di gestire endpoint Websocket come API REST ed endpoint RESTful come Websocket sul client. https://github.com/mikedeshazer/sockrest Inoltre, per coloro che stanno cercando di utilizzare un'API WebSocket sul client o viceversa nel modo in cui sono abituati. Il libs / sockrest.js chiarisce praticamente le differenze (o meglio dovrebbe).

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.