【问题标题】:NodeJS WebSocket Handshake Silently Failing?NodeJS WebSocket握手静默失败?
【发布时间】:2011-04-07 16:28:27
【问题描述】:

我正在尝试在 nodejs 中编写一个非常简单的 websocket 服务器,但遇到了一个问题。在浏览器上,WebSocket.onclose 函数是唯一被触发的函数(onopen、onmessage 和 onerror 不是)。我已经在 Chrome7 和 FireFox4 中进行了测试。这是我的服务器代码:

var http = 要求('http'), 净 = 要求('净'), 加密 = 要求('加密'); var server = http.createServer(function (req, res) { 控制台.log(req); }); server.on('connection', function (stream) { stream.setEncoding('utf8'); 流.setTimeout(0); 流.setNoDelay(true); stream.on('数据',函数(数据){ 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("****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 协议握手\r\n升级:WebSocket\r\n连接:升级\r\nSec-WebSocket-Origin:" + 来源 + "\r\nSec-WebSocket-Location: ws://127.0.0.1:8124/\r\n" + md5.digest('二进制'); stream.write(响应,'二进制'); console.log("****Outgoing****\r\n" + response); }); }); server.listen(8124, '127.0.0.1');

还有我的客户代码:

函数连接(){ 如果(窗口。WebSocket){ 尝试 { ws = new WebSocket('ws://127.0.0.1:8124'); ws.onopen = 函数 () { 警报(“打开”); }; ws.onclose = 函数() { 警报(“关闭”); }; ws.onerror = 函数(错误){ 警报(“错误!”); }; ws.onmessage = 函数() { 警报('消息'); }; } 抓住(前){ 警报(例如); } } }

【问题讨论】:

  • 您真的应该使用parseInt(..., 10) 来确保您将字符串解析为以10 为基数的数字。否则,你会得到奇怪的结果:parseInt("070") === 56.

标签: node.js websocket


【解决方案1】:

好吧,这里有一些问题,只触发 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

【讨论】:

  • #3 恰到好处。我的空间计算不正确。感谢您的帮助和链接。
【解决方案2】:

你可以监听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');

//...
}

【讨论】:

    猜你喜欢
    • 2015-03-16
    • 1970-01-01
    • 2014-01-04
    • 2023-03-05
    • 2021-11-13
    • 2018-11-26
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多