Perché utilizzare AJAX quando WebSockets è disponibile?

Ho usato WebSockets per un po ‘di tempo, ho scelto di creare uno strumento di gestione del progetto Agile per il mio progetto per l’ultimo anno presso l’Università che utilizza server Node e WebSockets. Ho scoperto che l’uso di WebSockets ha consentito un aumento del 624% del numero di richieste al secondo che la mia applicazione poteva elaborare.

Tuttavia da quando ho avviato il progetto ho letto delle falle nella sicurezza e alcuni browser che hanno scelto di disabilitare WebSockets per impostazione predefinita.

Questo mi porta alla domanda:

Perché utilizzare AJAX quando WebSockets sembra fare un così grande lavoro di riduzione della latenza e dell’overhead delle risorse, c’è qualcosa che AJAX fa meglio dei WebSockets?

WebSockets non ha lo scopo di sostituire AJAX e non è strettamente nemmeno un sostituto per Comet / long-poll (anche se ci sono molti casi in cui ciò ha senso).

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

Tuttavia, esiste sicuramente una sovrapposizione tra WebSockets e AJAX / Comet. Ad esempio, quando il browser vuole essere avvisato degli eventi del server (cioè push), le tecniche Comet e WebSockets sono certamente entrambe opzioni valide. Se l’applicazione richiede eventi push a bassa latenza, questo sarebbe un fattore a favore di WebSockets. D’altra parte, se è necessario coesistere con framework esistenti e tecnologie implementate (OAuth, API RESTful, proxy, load balancer), questo sarebbe un fattore a favore delle tecniche Comet (per ora).

Se non hai bisogno dei benefici specifici forniti da WebSockets, allora è probabilmente un’idea migliore attenersi a tecniche esistenti come AJAX e Comet perché questo ti permette di riutilizzare e integrare con un enorme ecosistema esistente di strumenti, tecnologie, meccanismi di sicurezza , basi di conoscenza (cioè molte più persone su StackOverflow conoscono HTTP / Ajax / Comet che WebSockets), ecc.

D’altra parte, se si sta creando una nuova applicazione che non funziona bene all’interno della latenza e dei vincoli di connessione di HTTP / Ajax / Comet, allora si consideri l’utilizzo di WebSockets.

Inoltre, alcune risposte indicano che uno dei lati negativi di WebSockets è il supporto per server e browser limitato / misto. Permettetemi di diffonderlo un po ‘. Mentre iOS (iPhone, iPad) supporta ancora il protocollo precedente (Hixie), la maggior parte dei server WebSockets supporta sia Hixie che la versione HyBi / IETF 6455 . La maggior parte delle altre piattaforms (se non hanno già il supporto integrato) possono ottenere il supporto WebSockets tramite web-socket-js (polyfill basato su Flash). Questo copre la stragrande maggioranza degli utenti del web. Inoltre, se stai usando Node per il back-end del server, allora considera l’uso di Socket.IO che include web-socket-js come fallback e se anche questo non è disponibile (o disabilitato), ricadrà sull’uso della tecnica di Comet disponibile per il browser specificato.

Aggiornamento : iOS 6 ora supporta l’attuale standard HyBi / IETF 6455.

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

Tuttavia, questo non significa che Websockets sia riuscito a sostituire AJAX, almeno non completamente, soprattutto perché l’adattamento HTTP / 2 è in aumento.

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

AJAX per il polling?

L’uso di AJAX per il polling (o polling lungo) sta scomparendo (e dovrebbe essere), ma rimane comunque in uso per due buoni motivi (principalmente per le applicazioni Web più piccole):

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

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

Tuttavia, Websocket push è di gran lunga superiore a AJAX (non è necessario eseguire nuovamente l’autenticazione o il reinvio delle intestazioni, non è necessario alcun “round” di dati, ecc.). Questo è stato discusso un numero di volte.

AJAX per REST?

Un utilizzo migliore per AJAX è le chiamate API REST. Questo uso semplifica la base del codice e impedisce il blocco della connessione Websocket (in particolare su caricamenti di dati di medie dimensioni).

Esistono numerosi validi motivi per preferire AJAX per le chiamate API REST e gli upload di dati:

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

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

  3. Con l’aumento del carico utile dei dati, le connessioni Websocket potrebbero essere bloccate a meno che la logica di frammentazione / multiplexing dei messaggi sia codificata.

    Se un caricamento viene eseguito in una singola chiamata di send Websocket, potrebbe bloccare un stream Websocket fino al termine del caricamento. Ciò ridurrà le prestazioni, specialmente sui client più lenti.

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

Tuttavia, per progetti più grandi, la flessibilità offerta da Websockets e l’equilibrio tra complessità del codice e gestione delle risorse porteranno l’equilibrio a favore di Websockets.

Ad esempio, i caricamenti basati su Websocket potrebbero offrire la possibilità di riprendere grandi caricamenti dopo che una connessione è stata interrotta e ristabilita (ricorda che film da 5 GB hai voluto caricare?).

Codificando la logica di frammentazione del caricamento, è facile riprendere un caricamento interrotto (la parte difficile è stata la codifica della cosa).

Che dire di push HTTP / 2?

Probabilmente dovrei aggiungere che la funzione push di HTTP / 2 non (e probabilmente non può) sostituire Websockets.

Questo è stato discusso qui prima, ma basti ricordare che una singola connessione HTTP / 2 serve l’intero browser (tutte le tabs / windows), 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 dati direttamente a una specifica scheda / finestra del browser.

Mentre i Websocket sono ottimi per la comunicazione bidirezionale dei dati, AJAX ha ancora portato un certo numero di vantaggi, specialmente quando si considerano carichi utili più grandi (caricamenti, ecc.).

E sicurezza?

Bene, generalmente, più fiducia e controllo vengono offerti a un programmatore, più potente è lo strumento … e più problemi di sicurezza si insinuano.

AJAX per natura avrebbe il sopravvento, dal momento che la sicurezza è incorporata 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 Websockets sono di solito errori nel codice dell’applicazione che ha introdotto un difetto di sicurezza (solitamente la logica di autenticazione di backend è dove li troverai).

Personalmente non trovo che questa sia una grande differenza, semmai penso che Websockets stia leggermente meglio, specialmente quando sai cosa stai facendo.

La mia umile opinione

IMHO, userei Websockets per tutto tranne le chiamate API REST. Caricamenti di dati di grandi dimensioni vorrei frammentare e inviare su Websockets quando ansible.

Polling, IMHO, dovrebbero essere messi fuori legge, il costo del traffico di rete è orribile e Websocket push è abbastanza facile da gestire anche per i nuovi sviluppatori.

Oltre ai problemi con i browser più vecchi (incluso IE9, dato che WebSockets sarà supportato a partire da IE10), ci sono ancora grossi problemi con gli intermediari di rete che non supportano ancora WebSockets, inclusi proxy trasparenti, proxy inversi e load balancer. Ci sono alcuni operatori di telefonia mobile che bloccano completamente il traffico WebSocket (cioè, dopo il comando HTTP UPGRADE).

Con il passare degli anni, WebSockets sarà sempre più supportato, ma nel frattempo si dovrebbe sempre disporre di un metodo fall-back basato su HTTP per l’invio di dati ai browser.

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

I WebSocket non funzionano nei browser Web meno recenti e quelli che lo supportano hanno spesso implementazioni differenti. Questa è praticamente l’unica buona ragione per cui non vengono utilizzati al posto di AJAX.

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

I Websocket sono un’ottima scelta per gestire lo streaming bidirezionale di dati a lunga durata quasi in tempo reale, mentre REST è ottimo per le comunicazioni occasionali. L’uso di websocket è un investimento considerevole, quindi è un eccesso di connessioni occasionali.

Potresti scoprire che Websockets funziona meglio quando sono presenti carichi elevati, in alcuni casi HTTP è leggermente più veloce perché può utilizzare la memorizzazione nella cache. Confrontando REST con Websockets è come paragonare le mele alle arance.

Dovremmo verificare quale fornisce una soluzione migliore per la nostra applicazione, quale si adatta meglio alle nostre vittorie nel caso d’uso.

Un esempio delle differenze tra HTTP e Websockets sotto forma di una lib di dimensioni client che può gestire endpoint Websocket come API REST e endpoint RESTful come Websockets sul client. https://github.com/mikedeshazer/sockrest Inoltre, per coloro che stanno tentando di utilizzare un’API websocket sul client o viceversa nel modo in cui sono abituati. Il libs / sockrest.js praticamente chiarisce le differenze (o meglio si suppone).