web-dev-qa-db-fra.com

Uncaught InvalidStateError: Échec de l'exécution de l'envoi sur WebSocket

Lorsque ma page se charge, j'essaie de send un message au serveur pour établir une connexion, mais cela ne fonctionne pas. Ce bloc de script est situé en haut de mon fichier:

var connection = new WrapperWS();
connection.ident();
// var autoIdent = window.addEventListener('load', connection.ident(), false);

La plupart du temps, je vois l'erreur dans le titre:

Uncaught InvalidStateError: Échec de l'exécution de l'envoi sur WebSocket

J'ai donc essayé de catch l'exception, comme vous pouvez le voir ci-dessous, mais maintenant, il semble que InvalidStateError n'est pas défini et que produit un ReferenceError.

Voici l'objet wrapper pour ma connexion websocket:

// Define WrapperWS

function WrapperWS() {
    if ("WebSocket" in window) {
        var ws = new WebSocket("ws://server:8000/");
        var self = this;

        ws.onopen = function () {
            console.log("Opening a connection...");
            window.identified = false;
        };
        ws.onclose = function (evt) {
            console.log("I'm sorry. Bye!");
        };
        ws.onmessage = function (evt) {
            // handle messages here
        };
        ws.onerror = function (evt) {
            console.log("ERR: " + evt.data);
        };

        this.write = function () {
            if (!window.identified) {
                connection.ident();
                console.debug("Wasn't identified earlier. It is now.");
            }
            ws.send(theText.value);
        };

        this.ident = function () {
            var session = "Test";
            try {
                ws.send(session);
            } catch (error) {
                if (error instanceof InvalidStateError) {
                    // possibly still 'CONNECTING'
                    if (ws.readyState !== 1) {
                        var waitSend = setInterval(ws.send(session), 1000);
                    }
                }
            }
        window.identified = true;
            theText.value = "Hello!";
            say.click();
            theText.disabled = false;
        };

    };

}

Je teste en utilisant Chromium sur Ubuntu.

28
icedwater

Vous pouvez envoyer des messages via une fonction proxy qui attend que l'état ready soit à 1.

this.send = function (message, callback) {
    this.waitForConnection(function () {
        ws.send(message);
        if (typeof callback !== 'undefined') {
          callback();
        }
    }, 1000);
};

this.waitForConnection = function (callback, interval) {
    if (ws.readyState === 1) {
        callback();
    } else {
        var that = this;
        // optional: implement backoff for interval here
        setTimeout(function () {
            that.waitForConnection(callback, interval);
        }, interval);
    }
};

Ensuite, utilisez this.send à la place de ws.send et mettez le code à exécuter ultérieurement dans un rappel:

this.ident = function () {
    var session = "Test";
    this.send(session, function () {
        window.identified = true;
        theText.value = "Hello!";
        say.click();
        theText.disabled = false;
    });
};

Pour quelque chose de plus simple, vous pouvez consulter promesses .

24
Gigablah

si vous utilisez un seul objet client Websocket et que vous vous connectez à partir d’applications aléatoires, cet objet peut être en mode connexion (accès concurent).

si vous voulez échanger via un seul websoket, alors créez une classe avec promise et conservez-la dans la propriété

class Ws {
  get newClientPromise() {
    return new Promise((resolve, reject) => {
      let wsClient = new WebSocket("ws://demos.kaazing.com/echo");
      console.log(wsClient)
      wsClient.onopen = () => {
        console.log("connected");
        resolve(wsClient);
      };
      wsClient.onerror = error => reject(error);
    })
  }
  get clientPromise() {
    if (!this.promise) {
      this.promise = this.newClientPromise
    }
    return this.promise;
  }
}

créer un singleton

window.wsSingleton = new Ws()

utiliser la propriété clientPromise à n'importe quel endroit de l'application

window.wsSingleton.clientPromise
  .then( wsClient =>{wsClient.send('data'); console.log('sended')})
  .catch( error => alert(error) )

http://jsfiddle.net/adqu7q58/11/

0
Ramil Gilfanov