2010-09-03 8 views
1

J'essaie d'écrire un serveur websocket très simple dans nodejs, et je rencontre un problème. Sur le navigateur, la fonction WebSocket.onclose est la seule qui est déclenchée (onopen, onmessage et onerror ne le sont pas). J'ai testé dans Chrome7 et FireFox4. Voici mon code serveur:Poignée de main NodeJS WebSocket en panne?

 
var http = require('http'), 
    net = require('net'), 
crypto = require('crypto'); 

var server = http.createServer(function (req, res) { 
console.log(req); 
}); 

server.on('connection', function (stream) { 
stream.setEncoding('utf8'); 
stream.setTimeout(0); 
stream.setNoDelay(true); 
stream.on('data', function (data) { 
    var sec1_regex = /Sec-WebSocket-Key1:(.*)/g; 
    var sec2_regex = /Sec-WebSocket-Key2:(.*)/g; 
    var origin_regex = /Origin: (.*)/g; 
    var protocol_regex = /Sec-WebSocket-Protocol: (.*)/g; 

    console.log(stream); 
    console.log("****Incoming****\r\n" + data); 
    var key1 = sec1_regex.exec(data)[1]; 
    var num1 = parseInt(key1.match(/\d/g).join(''))/(key1.match(/\s/g).length - 1); 
    console.log("num1: " + num1); 
    var key2 = sec2_regex.exec(data)[1]; 
    var num2 = parseInt(key2.match(/\d/g).join(''))/(key2.match(/\s/g).length - 1); 
    console.log("num2: " + num2); 
    var lastbytes = data.slice(-8); 
    var origin = origin_regex.exec(data)[1]; 

    var md5 = crypto.createHash('md5'); 
    md5.update(String.fromCharCode(num1 >> 24 & 0xFF, num1 >> 16 & 0xFF, num1 >> 8 & 0xFF, num1 & 0xFF)); 
    md5.update(String.fromCharCode(num2 >> 24 & 0xFF, num2 >> 16 & 0xFF, num2 >> 8 & 0xFF, num2 & 0xFF)); 
    md5.update(lastbytes); 
    var response = "HTTP/1.1 101 WebSocket Protocol Handshake\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\nSec-WebSocket-Origin: " 
    + origin + "\r\nSec-WebSocket-Location: ws://127.0.0.1:8124/\r\n" + 
     md5.digest('binary'); 
    stream.write(response, 'binary'); 
    console.log("****Outgoing****\r\n" + response); 
}); 
}); 

server.listen(8124, '127.0.0.1'); 

Et mon code client:

 

    function connect() { 
    if (window.WebSocket) { 
    try { 
    ws = new WebSocket('ws://127.0.0.1:8124'); 
    ws.onopen = function() { 
     alert("open"); 
    }; 
    ws.onclose = function() { 
     alert("close"); 
    }; 
    ws.onerror = function(err) { 
     alert("err!"); 
    }; 
    ws.onmessage = function() { 
     alert('message'); 
    }; 
    } catch (ex) { 
    alert(ex); 
    } 
    } 
    } 
    
+0

Vous devriez vraiment utiliser 'parseInt (..., 10)' pour vous assurer que vous analyse de la chaîne comme un numéro de base 10. Sinon, vous pouvez obtenir des résultats étranges: 'parseInt (" 070 ") === 56'. – pimvdb

Répondre

2

OK il y a deux ou trois choses mal ici, la raison pour laquelle est tiré que la poignée onclose est parce que le navigateur ne reçoit pas handshake valide et met donc fin à la connexion.

  1. Vous envoyez toujours ws://127.0.0.1:8124/ comme l'emplacement, l'emplacement doit correspondre exactement à ce que le navigateur envoie la demande dans ce cas, il serait plus probable localhost:8124 donc vous devriez revenir ws://localhost:8124/ dans un tel cas.

  2. Il vous manque un autre \r\n après les en-têtes de réponse, donc vous n'envoyez aucun corps.

  3. Il semble y avoir quelque chose de mal avec votre calcul de la valeur de hachage, je suis encore à essayer de comprendre ce que (le code toux est pas lisible après tout toux)

Pour un travail (et assez petit) voir la mise en œuvre ici:
http://github.com/BonsaiDen/NodeGame-Shooter/blob/master/server/ws.js

+0

# 3 était sur place. Le calcul de mes espaces était incorrect. Merci pour l'aide et le lien. – user438629

1

vous pouvez écouter l'événement de mise à niveau du serveur http.

il aime:

httpserver.onupgrade = function(request, socket) { 
var key = request.headers['sec-websocket-key']; 
key = require('crypto').createHash('sha1').update(key+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest('base64'); 

var sResponse = "HTTP/1.1 101 Switching Protocols\r\n" + 
    "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + 
    "Sec-WebSocket-Accept: " + key + "\r\n\r\n"; 
    socket.write(sResponse,'ascii'); 

//... 
}