我在https://stackoverflow.com/a/10402443/2755042上找到了一篇帖子,解释了如何编码/构造和解码Websocket数据。我在编码部分遇到了麻烦。我能够从客户端成功获取数据并将其记录到控制台,但是当我转过身并重新编码该消息并将其发送回客户端时,出现错误:

net.js:614
throw new TypeError('invalid data');
      ^
TypeError: invalid data


这是我的编码代码:

function encodeWebSocket(bytesRaw){
  var bytesFormatted = new Array();
  bytesFormatted[0] = 129;
  if (bytesRaw.length <= 125) {
    bytesFormatted[1] = bytesRaw.length;
  } else if (bytesRaw.length >= 126 && bytesRaw.length <= 65535) {
    bytesFormatted[1] = 126;
    bytesFormatted[2] = ( bytesRaw.length >> 8 ) & 255;
    bytesFormatted[3] = ( bytesRaw.length      ) & 255;
  } else {
    bytesFormatted[1] = 127;
    bytesFormatted[2] = ( bytesRaw.length >> 56 ) & 255;
    bytesFormatted[3] = ( bytesRaw.length >> 48 ) & 255;
    bytesFormatted[4] = ( bytesRaw.length >> 40 ) & 255;
    bytesFormatted[5] = ( bytesRaw.length >> 32 ) & 255;
    bytesFormatted[6] = ( bytesRaw.length >> 24 ) & 255;
    bytesFormatted[7] = ( bytesRaw.length >> 16 ) & 255;
    bytesFormatted[8] = ( bytesRaw.length >>  8 ) & 255;
    bytesFormatted[9] = ( bytesRaw.length       ) & 255;
  }
  for (var i = 0; i < bytesRaw.length; i++){
    bytesFormatted.push(bytesRaw.charCodeAt(i));
  }
  return bytesFormatted;
}


以下是使用encodeWebSocket函数的代码:

server.on('connection', function (socket) {
  socket.on('data', function (data) {
    // from client i send 'hello'
    var decodedMessage = (decodeWebSocket(data));
    console.log(decodedMessage); // hello
    console.log(typeof decodedMessage); // string
    var encodedMessage = encodeWebSocket(decodedMessage);
    socket.write(encodedMessage);
  });
});


本质上,我要做的就是创建一个聊天服务器,该服务器接受一条消息,然后转身将其发送回所有其他已连接的客户端。

任何帮助深表感谢。

最佳答案

Cade的答案中的代码是一个合理的起点。但是,以下代码可以解决一些问题。

首先,在处理unicode时,字符串长度和相应的缓冲区长度可能存在差异。例如:

> s = 'a'
'a'
> s.length
1
> b = new Buffer(s, 'utf-8')
<Buffer 61>
> b.length
1


但:

> s = 'å'
'å'
> s.length
1
> b = new Buffer(s, 'utf-8')
<Buffer c3 a5>
> b.length
2


因此,最好先将数据编码为缓冲区,然后再将缓冲区的长度用作有效负载长度。

同样,有效载荷长度可能> 0xffff,其中有效载荷长度需要八个字节,而不是两个字节。

以下代码中的其他两个小区别是添加了可选的回调并将写入合并为单个调用。虽然写操作可能会被缓冲,但它们可能是两个系统调用。

function send(data, encoding, callback) {
  var socket = this;
  var header;
  var payload = new Buffer(data, encoding);
  var len = payload.length;
  if (len <= 125) {
    header = new Buffer(2);
    header[1] = len;
  } else if (len <= 0xffff) {
    header = new Buffer(4);
    header[1] = 126;
    header[2] = (len >> 8) & 0xff;
    header[3] = len & 0xff;
  } else { /* 0xffff < len <= 2^63 */
    header = new Buffer(10);
    header[1] = 127;
    header[2] = (len >> 56) & 0xff;
    header[3] = (len >> 48) & 0xff;
    header[4] = (len >> 40) & 0xff;
    header[5] = (len >> 32) & 0xff;
    header[6] = (len >> 24) & 0xff;
    header[7] = (len >> 16) & 0xff;
    header[8] = (len >> 8) & 0xff;
    header[9] = len & 0xff;
  }
  header[0] = 0x81;
  socket.write(Buffer.concat([header, payload], header.length + payload.length), 'binary', callback);
}

关于javascript - 如何在JavaScript中构建Websocket数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25189006/

10-09 17:48
查看更多