Not: Bu, kesin çerçeveleme biçimine göre gelen ve giden WebSocket mesajlarını işleyebilen çok önemsiz bir sunucunun nasıl uygulanacağına dair bazı açıklama ve sözde koddur. El sıkışma sürecini içermez. Ayrıca bu cevap eğitim amaçlı yapılmıştır; tam özellikli bir uygulama değildir.
Özellikler (RFC 6455)
Mesaj gönderme
(Başka bir deyişle, sunucu → tarayıcı)
Gönderdiğiniz çerçevelerin WebSocket çerçeveleme formatına göre formatlanması gerekir. Mesaj göndermek için bu format aşağıdaki gibidir:
- veri türünü içeren bir bayt (ve önemsiz bir sunucu için kapsam dışı olan bazı ek bilgiler)
- uzunluğu içeren bir bayt
- uzunluk ikinci bayta uymuyorsa iki veya sekiz bayt (ikinci bayt, uzunluk için kaç bayt kullanıldığını belirten bir koddur)
- gerçek (ham) veriler
İlk bayt bir metin çerçevesi için 1000 0001
(veya 129
) olacaktır .
İkinci baytın ilk biti olarak ayarlanmıştır 0
çünkü verileri kodlamıyoruz (sunucudan istemciye kodlama zorunlu değildir).
Uzunluk baytlarını doğru gönderebilmek için ham verilerin uzunluğunu belirlemek gerekir:
- eğer
0 <= length <= 125
, ek bayt gerekmez
126 <= length <= 65535
iki ek bayta ihtiyacınız varsa ve ikinci bayta126
length >= 65536
sekiz ek bayta ihtiyacınız varsa ve ikinci bayta127
Uzunluğun ayrı baytlara bölünmesi gerekir, bu da sağa (sekiz bitlik bir miktarla) bit kaydırmanız ve sonra yalnızca son sekiz biti yaparak AND 1111 1111
(yani 255
) tutmanız gerektiği anlamına gelir .
Uzunluk bayt (lar) ından sonra ham veriler gelir.
Bu, aşağıdaki sözde koda yol açar:
bytesFormatted[0] = 129
indexStartRawData = -1 // it doesn't matter what value is
// set here - it will be set now:
if bytesRaw.length <= 125
bytesFormatted[1] = bytesRaw.length
indexStartRawData = 2
else if bytesRaw.length >= 126 and bytesRaw.length <= 65535
bytesFormatted[1] = 126
bytesFormatted[2] = ( bytesRaw.length >> 8 ) AND 255
bytesFormatted[3] = ( bytesRaw.length ) AND 255
indexStartRawData = 4
else
bytesFormatted[1] = 127
bytesFormatted[2] = ( bytesRaw.length >> 56 ) AND 255
bytesFormatted[3] = ( bytesRaw.length >> 48 ) AND 255
bytesFormatted[4] = ( bytesRaw.length >> 40 ) AND 255
bytesFormatted[5] = ( bytesRaw.length >> 32 ) AND 255
bytesFormatted[6] = ( bytesRaw.length >> 24 ) AND 255
bytesFormatted[7] = ( bytesRaw.length >> 16 ) AND 255
bytesFormatted[8] = ( bytesRaw.length >> 8 ) AND 255
bytesFormatted[9] = ( bytesRaw.length ) AND 255
indexStartRawData = 10
// put raw data at the correct index
bytesFormatted.put(bytesRaw, indexStartRawData)
// now send bytesFormatted (e.g. write it to the socket stream)
Mesajları almak
(Başka bir deyişle, tarayıcı → sunucu)
Elde ettiğiniz çerçeveler aşağıdaki formattadır:
- veri türünü içeren bir bayt
- uzunluğu içeren bir bayt
- uzunluk ikinci bayta sığmadıysa iki veya sekiz ek bayt
- maskeler olan dört bayt (= kod çözme anahtarları)
- gerçek veriler
İlk bayt genellikle önemli değildir - yalnızca metin gönderiyorsanız, yalnızca metin türünü kullanıyorsunuzdur. Bu durumda 1000 0001
(veya 129
) olacaktır .
İkinci bayt ve ek iki veya sekiz bayt biraz ayrıştırılmalıdır, çünkü uzunluk için kaç bayt kullanıldığını bilmeniz gerekir (gerçek verilerin nerede başladığını bilmeniz gerekir). Verilere zaten sahip olduğunuz için uzunluğun kendisi genellikle gerekli değildir.
İkinci baytın ilk biti her zaman 1
veri maskelenir (= kodlanır) anlamına gelir. İstemciden sunucuya gönderilen mesajlar her zaman maskelenir. Yaparak ilk parçayı kaldırmanız gerekir secondByte AND 0111 1111
. Ortaya çıkan baytın, ikinci bayta sığmadığı için uzunluğu temsil etmediği iki durum vardır:
- ikinci bir bayt
0111 1110
veya 126
, aşağıdaki iki baytın uzunluk için kullanıldığı anlamına gelir
- ikinci bir bayt
0111 1111
veya 127
, uzunluk için aşağıdaki sekiz baytın kullanıldığı anlamına gelir
Dört maske baytı, gönderilen gerçek verilerin kodunu çözmek için kullanılır. Kod çözme algoritması aşağıdaki gibidir:
decodedByte = encodedByte XOR masks[encodedByteIndex MOD 4]
burada encodedByte
veriler orijinal bayt olup, encodedByteIndex
birinci bayttan bayt sayım göstergesi (ofset) olan gerçek veri indeksine sahiptir, 0
. masks
dört maske baytını içeren bir dizidir.
Bu, kod çözme için aşağıdaki sözde koda yol açar:
secondByte = bytes[1]
length = secondByte AND 127 // may not be the actual length in the two special cases
indexFirstMask = 2 // if not a special case
if length == 126 // if a special case, change indexFirstMask
indexFirstMask = 4
else if length == 127 // ditto
indexFirstMask = 10
masks = bytes.slice(indexFirstMask, 4) // four bytes starting from indexFirstMask
indexFirstDataByte = indexFirstMask + 4 // four bytes further
decoded = new array
decoded.length = bytes.length - indexFirstDataByte // length of real data
for i = indexFirstDataByte, j = 0; i < bytes.length; i++, j++
decoded[j] = bytes[i] XOR masks[j MOD 4]
// now use "decoded" to interpret the received data
1000 0001
Metin çerçevesi için neden (129)? Spec diyor diyor:%x1 denotes a text frame
. Yani0000 0001
(0x01
) veya?