web-dev-qa-db-fra.com

javascript websockets - contrôle la connexion initiale/quand onOpen est-il lié

Deux questions connexes qui sont peut-être plus liées à mon manque de connaissances sur la manière dont/si les navigateurs pré-analysent javascript:

var ws = new WebSocket("ws://ws.my.url.com");
ws.onOpen = function() { ... };

Il semble n'y avoir aucun moyen de contrôler directement l'initialisation d'une WebSocket, à part l'envelopper dans un rappel, donc je suppose que la connexion est créée dès que le code javascript est chargé et est envoyée au constructeur?

Quand la propriété onOpen est-elle attachée à ws? Existe-t-il une possibilité de conditionnalité (si, pour une raison quelconque, vous aviez un code entre la définition du socket et celui de onOpen?) De sorte que onOpen soit lié de manière indécidable avant/après l’établissement de la connexion (je sais que vous pouvez éventuellement cochez ws.readyState). En plus de cela, la liaison WebSocket est-elle bloquante?

Je me rends compte que c’est un brouillon pour le moment, probablement lié à la mise en œuvre et que j’ai peut-être oublié quelque chose d’évident, mais je ne voyais rien de particulièrement pertinent dans mes recherches sur Internet/feuilletant brièvement le brouillon des spécifications W3C. Le fonctionnement interne de websockets/javascript est très apprécié!

26
dbeacham

JavaScript est à thread unique, ce qui signifie que la connexion réseau ne peut pas être établie tant que l'étendue actuelle de l'exécution n'est pas terminée et que l'exécution du réseau n'a aucune chance de s'exécuter. Le champ d’exécution pourrait être la fonction actuelle (la fonction connect dans l’exemple ci-dessous). Ainsi, vous pourriez rater l'événement onopen si vous vous y connectez très tard à l'aide de setTimeout, par exemple. dans cet exemple, vous pouvez manquer l'événement:

Voir: http://jsbin.com/ulihup/edit#javascript,html,live

Code:

var ws = null;

function connect() {
  ws = new WebSocket('ws://ws.pusherapp.com:80/app/a42751cdeb5eb77a6889?client=js&version=1.10');
  setTimeout(bindEvents, 1000);
  setReadyState();
}

function bindEvents() {
  ws.onopen = function() {
    log('onopen called');
    setReadyState();
  };
}

function setReadyState() {
  log('ws.readyState: ' + ws.readyState);
}

function log(msg) {
  if(document.body) {
    var text = document.createTextNode(msg);
    document.body.appendChild(text);
  }
}

connect();

Si vous exécutez l'exemple, vous constaterez peut-être que la ligne de journal 'onopen appelé' n'est jamais sortie. C'est parce que nous avons manqué l'événement.

Cependant, si vous conservez la fonction new WebSocket(...) et la liaison à l'événement onopen dans le même périmètre d'exécution, vous n'aurez aucune chance de rater l'événement.

Pour plus d'informations sur scope of execution et leur mise en file d'attente, leur planification et leur traitement, consultez l'article de John Resig sur Minuteries en JavaScript .

29
leggetter

Faites attention au fait que des E/S peuvent survenir dans le cadre de l'exécution ..__ Par exemple, dans le code suivant

var ws = new WebSocket("ws://localhost:8080/WebSockets/example");
alert("Hi");
ws.onopen = function(){
    writeToScreen("Web Socket is connected!!" + "<br>");
};
function writeToScreen(message) {
    var div = document.getElementById('test');
    div.insertAdjacentHTML( 'beforeend', message );
}

, le message "Web Socket is connected" apparaîtra ou non, en fonction du temps nécessaire à la fermeture de l'alerte "Hi"

2
Alon Halimi

@ leggetter a raison, le code suivant est exécuté séquentiellement:

(function(){
    ws = new WebSocket("ws://echo.websocket.org");
    ws.addEventListener('open', function(e){
        console.log('open', e);
        ws.send('test');
    });
    ws.addEventListener('message', function(e){console.log('msg', e)});

})();

Mais, dans spec W3C il y a une ligne curieuse: 

Renvoyez un nouvel objet WebSocket et poursuivez ces étapes en arrière-plan (sans bloquer les scripts).

C'était déroutant pour moi, lorsque j'apprenais l'api de navigateur pour cela. Je suppose que les agents utilisateurs l'ignorent ou que je l'interprète mal.

2
senz

Aucune entrée/sortie réelle ne se produira avant la fin de l'exécution du script. Il ne devrait donc pas y avoir de situation de concurrence critique.

1
Jacob