由于Chrome浏览器更新至V14,他们从去选秀三个版本,以草案八个版本。
我有一个在WebSocket上运行的内部聊天应用程序,尽管我已经开始使用新的握手了,但数据框架显然也发生了变化。我的WebSocket服务器基于Nugget。
是否有人让WebSocket与草案的第八版一起工作,并有一个示例,说明如何构造通过有线发送的数据?
(另请参见:如何在服务器端发送和接收WebSocket消息?)
这很容易,但是了解格式很重要。
第一个字节几乎始终是1000 0001,其中的1意思是“最后一帧”,三个0s是保留位,到目前为止没有任何意义0001,也意味着它是一个文本框架(Chrome使用该ws.send()方法发送)。
1000 0001
1
0
0001
ws.send()
( 更新: Chrome现在还可以发送带有的二进制帧ArrayBuffer。第一个字节的后四位是0002,因此您可以在文本数据和二进制数据之间进行区别。数据的解码方式完全相同。)
ArrayBuffer
0002
第二个字节包含一个1(表示已被“屏蔽”(编码)),后跟七个代表帧大小的位。如果介于000 0000和之间111 1101,则为大小。如果为111 1110,则后面的2个字节为长度(因为它不适合7个位),如果为111 1111,则下面的8个字节为长度(如果不适合两个字节)。
000 0000
111 1101
111 1110
111 1111
接下来是四个字节,它们是解码帧数据所需的“掩码”。这是使用异或编码完成的,异或编码使用indexOfByteInData mod 4数据定义的掩码之一。解码简单工作方式类似encodedByte xor maskByte(如果maskByte是indexOfByteInData mod 4)。
indexOfByteInData mod 4
encodedByte xor maskByte
maskByte
现在我必须说我完全没有C#经验,但这是一些伪代码(恐怕有些JavaScript口音):
var length_code = bytes[1] & 127, // remove the first 1 by doing '& 127' masks, data; if(length_code === 126) { masks = bytes.slice(4, 8); // 'slice' returns part of the byte array data = bytes.slice(8); // and accepts 'start' (inclusively) } else if(length_code === 127) { // and 'end' (exclusively) as arguments masks = bytes.slice(10, 14); // Passing no 'end' makes 'end' the length data = bytes.slice(14); // of the array } else { masks = bytes.slice(2, 6); data = bytes.slice(6); } // 'map' replaces each element in the array as per a specified function // (each element will be replaced with what is returned by the function) // The passed function accepts the value and index of the element as its // arguments var decoded = data.map(function(byte, index) { // index === 0 for the first byte return byte ^ masks[ index % 4 ]; // of 'data', not of 'bytes' // xor mod });
您还可以下载可能会有所帮助的规范(它当然包含了解格式所需的所有内容)。