नोट: यह कुछ स्पष्टीकरण और छद्म कोड के रूप में है कि कैसे एक बहुत ही तुच्छ सर्वर को लागू किया जाए जो निश्चित फ़्रेमिंग प्रारूप के अनुसार आने वाले और बाहर आने वाले वेबसैट संदेशों को संभाल सकता है। इसमें हैंडशेकिंग प्रक्रिया शामिल नहीं है। इसके अलावा, यह जवाब शैक्षिक उद्देश्यों के लिए बनाया गया है; यह पूर्ण विशेषताओं वाला कार्यान्वयन नहीं है।
विशिष्टता (RFC 6455)
संदेश भेजना
(दूसरे शब्दों में, सर्वर → ब्राउज़र)
वे फ़्रेम जिन्हें आप भेज रहे हैं, उन्हें WebSocket फ़्रेमिंग प्रारूप के अनुसार स्वरूपित करने की आवश्यकता है। संदेश भेजने के लिए, यह प्रारूप इस प्रकार है:
- एक बाइट जिसमें डेटा का प्रकार होता है (और कुछ अतिरिक्त जानकारी जो एक तुच्छ सर्वर के दायरे से बाहर है)
- एक बाइट जिसमें लंबाई होती है
- या तो दो या आठ बाइट्स यदि लंबाई दूसरी बाइट में फिट नहीं होती है (दूसरी बाइट तब एक कोड है जिसमें कहा जाता है कि लंबाई के लिए कितने बाइट्स का उपयोग किया जाता है)
- वास्तविक (कच्चा) डेटा
पहला बाइट एक टेक्स्ट फ़्रेम के लिए 1000 0001
(या 129
) होगा ।
दूसरे बाइट का पहला सेट है 0
क्योंकि हम डेटा को एन्कोडिंग नहीं कर रहे हैं (सर्वर से क्लाइंट के लिए एन्कोडिंग अनिवार्य नहीं है)।
कच्चे डेटा की लंबाई निर्धारित करना आवश्यक है ताकि लंबाई बाइट्स को सही ढंग से भेजा जा सके:
- यदि
0 <= length <= 125
, आपको अतिरिक्त बाइट्स की आवश्यकता नहीं है
- यदि
126 <= length <= 65535
, आपको दो अतिरिक्त बाइट्स की आवश्यकता है और दूसरा बाइट है126
- यदि
length >= 65536
, आपको आठ अतिरिक्त बाइट्स की आवश्यकता है, और दूसरी बाइट है127
लंबाई को अलग-अलग बाइट्स में कटा हुआ होना चाहिए, जिसका अर्थ है कि आपको दाईं ओर (आठ बिट्स की राशि के साथ) बिट-शिफ्ट करने की आवश्यकता होगी, और फिर केवल AND 1111 1111
(जो है 255
) करके पिछले आठ बिट्स को बनाए रखें ।
लंबाई बाइट के बाद कच्चा डेटा आता है।
यह निम्नलिखित छद्मकोश की ओर जाता है:
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)
संदेश प्राप्त करना
(दूसरे शब्दों में, ब्राउज़र → सर्वर)
आपके द्वारा प्राप्त फ़्रेम निम्नलिखित प्रारूप में हैं:
- एक बाइट जिसमें डेटा का प्रकार होता है
- एक बाइट जिसमें लंबाई होती है
- यदि दो या आठ अतिरिक्त बाइट्स हैं, तो लंबाई दूसरी बाइट में फिट नहीं होती है
- चार बाइट्स जो मास्क हैं (= डिकोडिंग कीज़)
- वास्तविक डेटा
पहला बाइट आमतौर पर मायने नहीं रखता है - यदि आप केवल पाठ भेज रहे हैं तो आप केवल पाठ प्रकार का उपयोग कर रहे हैं। यह उस मामले में 1000 0001
(या 129
) होगा ।
दूसरे बाइट और अतिरिक्त दो या आठ बाइट्स को कुछ पार्सिंग की आवश्यकता होती है, क्योंकि आपको यह जानने की आवश्यकता है कि लंबाई के लिए कितने बाइट्स का उपयोग किया जाता है (आपको यह जानना होगा कि वास्तविक डेटा कहाँ शुरू होता है)। आपके पास डेटा पहले से ही लंबाई आमतौर पर आवश्यक नहीं है।
दूसरी बाइट का पहला बिट हमेशा होता है 1
जिसका अर्थ है कि डेटा नकाब (= एन्कोडेड) है। क्लाइंट से सर्वर तक संदेश हमेशा नकाबपोश होते हैं। आपको उस पहले बिट को हटाने की आवश्यकता है secondByte AND 0111 1111
। ऐसे दो मामले हैं जिनमें परिणामी बाइट लंबाई का प्रतिनिधित्व नहीं करती है क्योंकि यह दूसरी बाइट में फिट नहीं होती है:
- की दूसरी बाइट
0111 1110
, या 126
, का अर्थ है कि निम्नलिखित दो बाइट्स लंबाई के लिए उपयोग किए जाते हैं
- की एक दूसरी बाइट
0111 1111
, या 127
, इसका मतलब है कि लंबाई के लिए निम्नलिखित आठ बाइट्स का उपयोग किया जाता है
चार मास्क बाइट्स का उपयोग वास्तविक डेटा को डिकोड करने के लिए किया जाता है जिसे भेजा गया है। डिकोडिंग के लिए एल्गोरिथ्म इस प्रकार है:
decodedByte = encodedByte XOR masks[encodedByteIndex MOD 4]
जहां encodedByte
डेटा में मूल बाइट है, वास्तविक डेटाencodedByteIndex
के पहले बाइट से बाइट काउंटिंग का सूचकांक (ऑफसेट) है , जिसमें इंडेक्स है । चार मुखौटा बाइट्स से युक्त एक सरणी है।0
masks
यह डिकोडिंग के लिए निम्नलिखित छद्मकोश की ओर जाता है:
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
टेक्स्ट फ्रेम के लिए क्यों (129)? युक्ति कहती है%x1 denotes a text frame
:। तो यह होना चाहिए0000 0001
(0x01
), या?