(Patrz także: How can I send and receive WebSocket messages on the server side?)
Jest to dość proste, ale ważne jest, aby zrozumieć format.
Pierwszy bajt jest prawie zawsze 1000 0001
, gdzie 1
oznacza „ostatnią klatkę”, trzy 0
s są tak daleko zastrzeżone bity bez znaczenia i 0001
oznacza, że jest to ramka tekstowa (który Chrome wysyła metodą ws.send()
).
(Aktualizacja:.. Chrome może teraz również wysłać ramek binarnych z ArrayBuffer
Ostatnie cztery bity pierwszego bajtu będzie 0002
, więc można się różnić między tekstu i danych binarnych Dekodowanie danych działa dokładnie tak ten sam sposób.)
Drugi bajt zawiera 1
(co oznacza, że jest "zamaskowany" (zakodowany)), po którym następuje siedem bitów, które reprezentują rozmiar ramki. Jeśli jest między 000 0000
i 111 1101
, to jest rozmiar. Jeśli jest to 111 1110
, następujące 2 bajty są długością (ponieważ nie zmieściłoby się w siedmiu bitach), a jeśli jest to 111 1111
, następujące 8 bajtów to długość (jeśli nie zmieściłaby się również w dwóch bajtach).
Poniżej znajdują się cztery bajty, które są "maskami", których potrzebujesz do dekodowania danych ramki. Odbywa się to za pomocą kodowania xor, które wykorzystuje jedną z masek zdefiniowanych przez indexOfByteInData mod 4
danych. Dekodowanie działa po prostu jako encodedByte xor maskByte
(gdzie maskByte
jest indexOfByteInData mod 4
).
Teraz muszę powiedzieć, że nie mam doświadczenie z C# w ogóle, ale to jest jakiś pseudokod (jakiś akcent JavaScript Obawiam):
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
});
Można również pobrać the specification, które mogą być pomocne (zawiera oczywiście wszystko, co jest potrzebne do zrozumienia formatu).
Słodko ... Wypróbuję to w poniedziałek. Dam ci zaakceptowaną odpowiedź, jeśli się uda ... :) – gislikonrad
W końcu udało mi się spojrzeć na to rozwiązanie dla mojego serwera websocket. Pracował jak czar ... Dzięki, człowieku ... – gislikonrad
@ Gísli Konráð: Świetnie się udało; WebSockets nie są tak naprawdę przyjazne debugowaniu. – pimvdb