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.
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 .
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) )