(См. Также: Как я могу отправлять и получать сообщения WebSocket на стороне сервера? )
Это довольно просто, но важно понимать формат.
Первый байт почти всегда равен 1000 0001
, где 1
означает «последний кадр», три 0
s являются зарезервированными битами без какого-либо значения, а 0001
означает, что это текстовый фрейм ( который Chrome отправляет методом ws.send()
).
( Обновление: Теперь Chrome также может отправлять двоичные кадры с ArrayBuffer
. Последние четыре бита первого байта будут 0002
, поэтому вы можете различать текстовые и двоичные данные. декодирование данных работает точно так же.)
Второй байт содержит 1
(что означает, что он «замаскирован» (кодирован)), за которым следуют семь битов, которые представляют размер кадра. Если это между 000 0000
и 111 1101
, это размер. Если это 111 1110
, следующие 2 байта являются длиной (потому что она не помещается в семь битов), а если это 111 1111
, следующие 8 байтов являются длиной (если она также не помещается в два байта) ).
Далее следуют четыре байта, которые являются «масками», которые вам нужны для декодирования данных кадра. Это делается с использованием xor-кодирования, которое использует одну из масок, как определено indexOfByteInData mod 4
данных. Декодирование просто работает как encodedByte xor maskByte
(где maskByte
равно indexOfByteInData 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
});
Вы также можете загрузить спецификацию , которая может быть полезна (она, конечно, содержит все необходимое для понимания формата).