一尘不染

如何在WebSockets hybi 08+中解构数据帧?

c#

由于Chrome浏览器更新至V14,他们从去选秀三个版本,以草案八个版本

我有一个在WebSocket上运行的内部聊天应用程序,尽管我已经开始使用新的握手了,但数据框架显然也发生了变化。我的WebSocket服务器基于Nugget

是否有人让WebSocket与草案的第八版一起工作,并有一个示例,说明如何构造通过有线发送的数据?


阅读 236

收藏
2020-05-19

共1个答案

一尘不染

(另请参见:如何在服务器端发送和接收WebSocket消息?


这很容易,但是了解格式很重要。

第一个字节几乎始终是1000 0001,其中的1意思是“最后一帧”,三个0s是保留位,到目前为止没有任何意义0001,也意味着它是一个文本框架(Chrome使用该ws.send()方法发送)。

更新:
Chrome现在还可以发送带有的二进制帧ArrayBuffer。第一个字节的后四位是0002,因此您可以在文本数据和二进制数据之间进行区别。数据的解码方式完全相同。)

第二个字节包含一个1(表示已被“屏蔽”(编码)),后跟七个代表帧大小的位。如果介于000 0000和之间111 1101,则为大小。如果为111 1110,则后面的2个字节为长度(因为它不适合7个位),如果为111 1111,则下面的8个字节为长度(如果不适合两个字节)。

接下来是四个字节,它们是解码帧数据所需的“掩码”。这是使用异或编码完成的,异或编码使用indexOfByteInData mod 4数据定义的掩码之一。解码简单工作方式类似encodedByte xor maskByte(如果maskByteindexOfByteInData mod 4)。

现在我必须说我完全没有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
});

您还可以下载可能会有所帮助的规范(它当然包含了解格式所需的所有内容)。

2020-05-19