如何在JavaScript中构建Websocket数据

如何在JavaScript中构建Websocket数据,javascript,websocket,Javascript,Websocket,我找到一篇文章,解释如何对websocket数据进行编码/帧和解码。我的编码部分有问题。我能够成功地从客户机获取数据并将其记录到控制台,但当我转身重新编码该消息并将其发送回客户机时,我收到一个错误: net.js:614 throw new TypeError('invalid data'); ^ TypeError: invalid data 以下是我的编码代码: function encodeWebSocket(bytesRaw){ var bytesFormatted =

我找到一篇文章,解释如何对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;
}
从本质上说,我所要做的就是创建一个聊天服务器,它接受一条消息,并将其发送回连接的所有其他客户端


非常感谢您的帮助。

经过大量搜索,以下是我设法获得的代码,用于对发送给客户端的数据进行编码:

function send(msg) {
  // http://stackoverflow.com/questions/8214910/node-js-websocket-send-custom-data
  var socket = this;
  var newFrame = new Buffer(msg.length > 125 ? 4 : 2);
  newFrame[0] = 0x81;
  if (msg.length > 125) {
    newFrame[1] = 126;
    var length = msg.length;
    newFrame[2] = length >> 8;
    newFrame[3] = length & 0xFF;
  }
  else {
    newFrame[1] = msg.length;
  }
  socket.write(newFrame, 'binary');
  socket.write(msg, 'utf8');
}

凯德回答中的代码是一个合理的开始。但在下面的代码中有几个要点可以解决

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

> s = 'a'
'a'
> s.length
1
> b = new Buffer(s, 'utf-8')
<Buffer 61>
> b.length
1
>s='a'
“a”
>美国长度
1.
>b=新缓冲区(s'utf-8')
>长度
1.
但是:

>s='å'
'å'
>美国长度
1.
>b=新缓冲区(s'utf-8')
>长度
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);
}
函数发送(数据、编码、回调){
var socket=这个;
var头;
var有效载荷=新缓冲区(数据、编码);
var len=有效载荷长度;
if(len 8)&0xff;
标题[3]=len&0xff;
}else{/*0xffff56)&0xff;
标题[3]=(len>>48)&0xff;
标题[4]=(len>>40)&0xff;
标题[5]=(len>>32)&0xff;
标题[6]=(len>>24)&0xff;
标题[7]=(len>>16)&0xff;
标题[8]=(len>>8)&0xff;
标题[9]=len&0xff;
}
头[0]=0x81;
写入(Buffer.concat([header,payload],header.length+payload.length),'binary',回调);
}

我认为您不完全理解上述代码的作用。它基本上看起来像一个位打包函数,允许您发送二进制数据。默认情况下,它发送文本;大多数人发送序列化的JSON对象。我同意你的观点,我不完全理解这个函数在做什么。如何让
decodedMessage
以正确的格式发送到
socket.write()
> s = 'å'
'å'
> s.length
1
> b = new Buffer(s, 'utf-8')
<Buffer c3 a5>
> b.length
2
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);
}