NodeJS тихая ошибка рукопожатия WebSocket? - PullRequest
2 голосов
/ 03 сентября 2010

Я пытаюсь написать очень простой сервер веб-сокетов в nodejs, и у меня возникла проблема.В браузере запускается только функция WebSocket.onclose (onopen, onmessage и onerror нет).Я тестировал в Chrome7 и FireFox4.Вот мой код сервера:

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

И код моего клиента:


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

Ответы [ 2 ]

2 голосов
/ 03 сентября 2010

ОК, здесь несколько вещей не так, причина, по которой срабатывает только дескриптор onclose, заключается в том, что браузер не получает правильное рукопожатие и поэтому прерывает соединение.

  1. Вы всегда отправляете ws://127.0.0.1:8124/ в качестве местоположения, местоположение должно точно совпадать с тем, что браузер отправляет в запросе, в этом случае, скорее всего, будет localhost:8124, поэтому вы должны вернуть ws://localhost:8124/ в таком случае .

  2. Вам не хватает еще одного \r\n после заголовков ответа, поэтому вы фактически не отправляете никакого тела.

  3. Кажется, что-то не так с вашим вычислением значения хеша, я все еще пытаюсь выяснить, что хотя

Для работающей (и довольно маленькой) реализации смотрите здесь:
http://github.com/BonsaiDen/NodeGame-Shooter/blob/master/server/ws.js

1 голос
/ 20 сентября 2012

Вы можете прослушать событие обновления http-сервера.

нравится:

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

//...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...