2010-09-03 3 views
1

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

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

Вы действительно должны использовать 'ParseInt (..., 10)', чтобы убедиться, что вы разбираете строку в качестве базового 10 числа. В противном случае вы можете получить странные результаты: 'parseInt (« 070 ») === 56'. – pimvdb

ответ

2

OK Есть несколько вещей, которые здесь не так, причина только 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

+0

# 3 был место сверху. Расчет пробелов был неправильным. Спасибо за помощь и ссылку. – user438629

1

Вы можете прослушивать событие обновления сервера 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'); 

//... 
} 
Смежные вопросы