it-swarm.com.de

Nicht abgerufen InvalidStateError: Fehler beim Ausführen von 'send' für 'WebSocket': Immer noch im Status CONNECTING

Wenn meine Seite geladen wird, versuche ich eine send-Nachricht an den Server zu senden, um eine Verbindung herzustellen, die jedoch nicht funktioniert. Dieser Skriptblock befindet sich oben in meiner Datei:

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

Meistens sehe ich den Fehler im Titel:

Nicht abgerufen InvalidStateError: Fehler beim Ausführen von 'send' für 'WebSocket': Immer noch im Status CONNECTING

Also habe ich versucht, die Ausnahme zu catch zu machen, wie Sie unten sehen können, aber jetzt scheint InvalidStateError nicht definiert zu sein und dies erzeugt eine ReferenceError.

Hier ist das Wrapper-Objekt für meine Websocket-Verbindung:

// 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;
        };

    };

}

Ich teste mit Chromium auf Ubuntu.

28
icedwater

Sie können Nachrichten über eine Proxy-Funktion senden, die darauf wartet, dass der readyState 1 ist.

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);
    }
};

Verwenden Sie dann this.send anstelle von ws.send und geben Sie den Code, der anschließend ausgeführt werden soll, in einen Rückruf ein:

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

Für etwas mehr gestrafft könnte man in Versprechen schauen.

24
Gigablah

wenn Sie ein Websocket-Client-Objekt verwenden und eine Verbindung von zufälligen App-Bereichen herstellen, kann sich das Objekt im Verbindungsmodus befinden (konvergenter Zugriff).

wenn Sie nur über ein Websoket austauschen möchten, erstellen Sie eine Klasse mit promise .__

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;
  }
}

singleton erstellen

window.wsSingleton = new Ws()

verwenden Sie die clientPromise-Eigenschaft an einem beliebigen Ort der App

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

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

0
Ramil Gilfanov