Risoluzione della congestione della richiesta al browser utilizzando socket come "corsia veloce", nessuna conseguenza?

2

Ho ricevuto più report dagli utenti di un'applicazione GIS basata sul Web che abbiamo implementato uno o due anni fa, lamentando che l'applicazione diventasse instabile / non rispondente. Dopo una breve indagine, ho scoperto che le richieste dell'API di mappe di terze parti occupano la maggior parte delle connessioni disponibili dei browser (estrapolando i livelli dinamici, sono immagini ) e il tempo di elaborazione di queste richieste è stato prolungato a causa di un numero elevato di utenti (1xx vs 1x come pianificato), quindi le richieste della nostra API hanno dovuto attendere connessioni libere e alla fine il timeout, la panoramica di tale situazione è simile a questa:

requests from the Map API (busy) | requests from our own API to get data from DB to display (waiting) | requests from our own API to post data to DB (waiting)

** A FEW MOMENTS LATER **

requests from the Map API (still working...) | requests from our own API to get data from DB to display (timeout) | requests from our own API to post data to DB (timeout)

ciò che voglio ottenere è spostare qualsiasi richiesta dalla nostra API per ottenere dati dal DB davanti alle richieste dall'API della mappa, tuttavia, non è il modo di dire all'API della mappa che deve attendere (più importanti) richieste da la nostra API prima che potessero aggiornare la mappa. Mi sono imbattuto in questa domanda e ho pianificato di proporre una soluzione: apri un socket prima di inizializzare l'API di Map e le richieste dalla nostra stessa API per ottenere i dati passeranno attraverso di essa invece di usare ajax. Mi chiedo ...

Devo fare anche le richieste dalla nostra stessa API per inviare dati a DB anche usando il socket? Poiché l'API di riscrittura funziona con Ajax su Socket, richiede tempo e gli utenti dovrebbero pubblicare gli aggiornamenti dopo aver ottenuto i dati e la mappa aggiornata.

Inoltre, facendo ogni richiesta dalla nostra API tramite socket sembra spostare la congestione della richiesta da Ajax al socket.

    
posta Incognitoo 28.09.2018 - 05:29
fonte

1 risposta

2

La risposta breve è il pool di connessioni. È necessario disporre di un pool di oggetti XMLHttpRequest utilizzati per inviare richieste AJAX e tenere traccia di quelli in uso e di quelli gratuiti. Poiché il codice deve inviare una richiesta, fornisci una connessione gratuita.

Ma questo è JavaScript.

E c'è una libreria di terze parti coinvolta.

La risposta lunga è la "risposta breve" più un po 'di pollo Voodoo Magic ™

È probabile che il codice di terze parti invii richieste AJAX creando un'istanza di un oggetto new XMLHttpRequest direttamente o passando attraverso un'altra libreria come jQuery - $.ajax(...) - che usa semplicemente XMLHttpRequest sotto il cofano. Fortunatamente l'elemento comune è la classe XMLHttpRequest, che è un membro dell'oggetto window.

  1. Scrivi una classe per le connessioni di pool

  2. Scrivi una classe proxy per XMLHttpRequest con la stessa interfaccia pubblica (proprietà incluse) che ottiene in modo asincrono un oggetto XMLHttpRequest libero dal pool

  3. Assegna window.XMLHttpRequest a una variabile locale all'interno di una funzione di chiusura che racchiude l'intera libreria del pool di connessioni

  4. Assegna la tua classe proxy per XMLHttpRequest a window.XMLHttpRequest

  5. Includi questo script prima di tutti gli altri script

Ora quando un codice esegue new XMLHttpRequest() ciò che stanno ottenendo è il tuo oggetto XMLHttpRequestProxy, che delega al suo pool di connessioni interne. Anche le librerie di terze parti lo utilizzeranno. Poiché la classe XMLHttpRequestProxy ha la stessa interfaccia pubblica della classe XMLHttpRequest reale, le librerie di terze parti non conoscono la differenza.

Uno stub di base del file JavaScript sarebbe simile a:

(function (window) {
    var RawXMLHttpRequest = window.XMLHttpRequest;

    var requestPool = {
        // whatever you need to manage a pool of RawXMLHttpRequest objects

        getConnection: function () {
            // return a Promise
        }
    };

    function XMLHttpRequestProxy() {
        // Same properties and methods as real XMLHttpRequest

        var _xhr = null;

        function getConnection() {
            if (_xhr === null) {
                requestPool.getConnection()
                    .then(function (xhr) {
                        _xhr = xhr;

                        // return Promise, pass _xhr
                    });
            }

            // return Promise, pass _xhr
        }

        this.send = function(requestBody) {
            getConnection()
                .then(function (xhr) {
                    xhr.send(requestBody);
                });
        };
    }

    window.XMLHttpRequest = XMLHttpRequestProxy;
})(this);

Sebbene il codice nel seguente link non sia la soluzione al tuo problema specifico, illustra questo tipo di pattern: MockingBird.XMLHttpRequestInterceptor(global)

Avrai ancora dei giocolieri per fare in modo che i gestori di onreadystatechange vengano chiamati correttamente, e quindi la classe XMLHttpRequestProxy dice correttamente al pool quando un oggetto AJAX è in uso o liberato, ma il modello di base è lì.

    
risposta data 28.09.2018 - 14:06
fonte

Leggi altre domande sui tag