समस्या: क्लाइंट-सर्वर और सर्वर-क्लाइंट कनेक्शन में कम इंतज़ार का समय
वेब को मुख्य रूप से एचटीटीपी के अनुरोध/जवाब के मॉडल के आधार पर बनाया गया है. कोई क्लाइंट किसी वेब पेज को लोड करता है. इसके बाद, जब तक उपयोगकर्ता अगले पेज पर क्लिक नहीं करता, तब तक कुछ नहीं होता. साल 2005 के आस-पास, AJAX ने वेब को ज़्यादा डाइनैमिक बनाना शुरू किया. हालांकि, सभी एचटीटीपी कम्यूनिकेशन को क्लाइंट ही मैनेज करता था. इसके लिए, उपयोगकर्ता के इंटरैक्शन या सर्वर से नया डेटा लोड करने के लिए समय-समय पर पोलिंग की ज़रूरत होती थी.
ऐसी टेक्नोलॉजी काफ़ी समय से मौजूद हैं जो सर्वर को क्लाइंट को डेटा भेजने की सुविधा देती हैं. ऐसा तब होता है, जब सर्वर को पता चलता है कि नया डेटा उपलब्ध है. इन्हें 'पुश' या 'कॉमेट' जैसे नामों से जाना जाता है. सर्वर से शुरू किए गए कनेक्शन का भ्रम पैदा करने के लिए, सबसे आम हैकों में से एक को लॉन्ग पोलिंग कहा जाता है. लॉन्ग पोलिंग में, क्लाइंट सर्वर के लिए एक एचटीटीपी कनेक्शन खोलता है. यह कनेक्शन तब तक खुला रहता है, जब तक सर्वर जवाब नहीं भेज देता. जब भी सर्वर के पास असल में नया डेटा होता है, तो वह जवाब भेजता है. अन्य तकनीकों में Flash, XHR मल्टीपार्ट अनुरोध, और htmlfiles शामिल हैं. लॉन्ग पोलिंग और अन्य तकनीकें काफ़ी अच्छी तरह से काम करती हैं. इनका इस्तेमाल हर दिन Gmail चैट जैसे ऐप्लिकेशन में किया जाता है.
हालांकि, इन सभी तरीकों में एक समस्या है: इनमें एचटीटीपी का ओवरहेड होता है. इस वजह से, ये कम इंतज़ार के समय वाले ऐप्लिकेशन के लिए सही नहीं होते. जैसे, ब्राउज़र में खेले जाने वाले मल्टीप्लेयर फ़र्स्ट पर्सन शूटर गेम या रीयल-टाइम कॉम्पोनेंट वाला कोई अन्य ऑनलाइन गेम.
WebSocket के बारे में जानकारी: वेब पर सॉकेट की सुविधा
WebSocket की खास जानकारी में, वेब ब्राउज़र और सर्वर के बीच "सॉकेट" कनेक्शन बनाने वाले एपीआई के बारे में बताया गया है. आसान शब्दों में: क्लाइंट और सर्वर के बीच एक स्थायी कनेक्शन होता है. दोनों पक्ष किसी भी समय डेटा भेजना शुरू कर सकते हैं.
शुरू करना
WebSocket कंस्ट्रक्टर को कॉल करके, WebSocket कनेक्शन खोला जा सकता है:
var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);
ws: पर ध्यान दें. यह WebSocket कनेक्शन के लिए नया यूआरएल स्कीमा है. सुरक्षित WebSocket कनेक्शन के लिए, wss: का इस्तेमाल भी किया जाता है. ठीक उसी तरह, जिस तरह सुरक्षित एचटीटीपी कनेक्शन के लिए https: का इस्तेमाल किया जाता है.
कनेक्शन से कुछ इवेंट हैंडलर तुरंत अटैच करने पर, आपको पता चलता है कि कनेक्शन कब खुला, आने वाले मैसेज कब मिले या कोई गड़बड़ी कब हुई.
दूसरे आर्ग्युमेंट में, वैकल्पिक सब-प्रोटोकॉल स्वीकार किए जाते हैं. यह कोई स्ट्रिंग या स्ट्रिंग का कलेक्शन हो सकता है. हर स्ट्रिंग, सब-प्रोटोकॉल के नाम को दिखाती है. साथ ही, सर्वर अरे में पास किए गए सब-प्रोटोकॉल में से सिर्फ़ एक को स्वीकार करता है. स्वीकार किए गए सब-प्रोटोकॉल का पता लगाने के लिए, WebSocket ऑब्जेक्ट की protocol प्रॉपर्टी को ऐक्सेस करें.
सब-प्रोटोकॉल के नाम, आईएएनए रजिस्ट्री में रजिस्टर किए गए सब-प्रोटोकॉल के नामों में से एक होने चाहिए. फ़िलहाल, फ़रवरी 2012 तक सिर्फ़ एक सब-प्रोटोकॉल नाम (soap) रजिस्टर किया गया है.
// When the connection is open, send some data to the server
connection.onopen = function () {
connection.send('Ping'); // Send the message 'Ping' to the server
};
// Log errors
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
};
// Log messages from the server
connection.onmessage = function (e) {
console.log('Server: ' + e.data);
};
सर्वर से कम्यूनिकेट किया जा रहा है
सर्वर से कनेक्शन होते ही (जब open इवेंट ट्रिगर होता है), हम कनेक्शन ऑब्जेक्ट पर send('your message') तरीके का इस्तेमाल करके, सर्वर को डेटा भेजना शुरू कर सकते हैं. पहले इसमें सिर्फ़ स्ट्रिंग का इस्तेमाल किया जा सकता था. हालांकि, नई खास जानकारी के मुताबिक, अब इसमें बाइनरी मैसेज भी भेजे जा सकते हैं. बाइनरी डेटा भेजने के लिए, Blob या ArrayBuffer ऑब्जेक्ट का इस्तेमाल किया जा सकता है.
// Sending String
connection.send('your message');
// Sending canvas ImageData as ArrayBuffer
var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
binary[i] = img.data[i];
}
connection.send(binary.buffer);
// Sending file as Blob
var file = document.querySelector('input[type="file"]').files[0];
connection.send(file);
इसी तरह, सर्वर हमें किसी भी समय मैसेज भेज सकता है. जब भी ऐसा होता है, तब onmessage कॉलबैक ट्रिगर होता है. कॉलबैक को एक इवेंट ऑब्जेक्ट मिलता है और असल मैसेज को data प्रॉपर्टी के ज़रिए ऐक्सेस किया जा सकता है.
WebSocket, नई स्पेसिफ़िकेशन में बाइनरी मैसेज भी पा सकता है. बाइनरी फ़्रेम, Blob या ArrayBuffer फ़ॉर्मैट में मिल सकते हैं. मिले बाइनरी के फ़ॉर्मैट की जानकारी देने के लिए, WebSocket ऑब्जेक्ट की binaryType प्रॉपर्टी को 'blob' या 'arraybuffer' पर सेट करें. डिफ़ॉल्ट फ़ॉर्मैट 'blob' होता है. (आपको मैसेज भेजते समय, binaryType पैरामीटर को अलाइन करने की ज़रूरत नहीं है.)
// Setting binaryType to accept received binary as either 'blob' or 'arraybuffer'
connection.binaryType = 'arraybuffer';
connection.onmessage = function(e) {
console.log(e.data.byteLength); // ArrayBuffer object if binary
};
WebSocket में जोड़ी गई एक और नई सुविधा है, एक्सटेंशन. एक्सटेंशन का इस्तेमाल करके, फ़्रेम को कंप्रेस, मल्टीप्लेक्स वगैरह करके भेजा जा सकेगा. ओपन इवेंट के बाद, WebSocket ऑब्जेक्ट की एक्सटेंशन प्रॉपर्टी की जांच करके, सर्वर से स्वीकार किए गए एक्सटेंशन ढूंढे जा सकते हैं. फ़रवरी 2012 तक, एक्सटेंशन के लिए आधिकारिक तौर पर कोई खास जानकारी पब्लिश नहीं की गई है.
// Determining accepted extensions
console.log(connection.extensions);
क्रॉस-ऑरिजिन कम्यूनिकेशन
एक आधुनिक प्रोटोकॉल होने की वजह से, क्रॉस ऑरिजिन कम्यूनिकेशन को WebSocket में ही शामिल किया गया है. आपको अब भी यह पक्का करना चाहिए कि सिर्फ़ उन क्लाइंट और सर्वर से कम्यूनिकेट किया जाए जिन पर आपको भरोसा है. हालांकि, WebSocket की मदद से किसी भी डोमेन पर मौजूद पक्षों के बीच कम्यूनिकेशन किया जा सकता है. सर्वर यह तय करता है कि अपनी सेवा को सभी क्लाइंट के लिए उपलब्ध कराना है या सिर्फ़ उन क्लाइंट के लिए जो अच्छी तरह से तय किए गए डोमेन के सेट पर मौजूद हैं.
प्रॉक्सी सर्वर
हर नई टेक्नोलॉजी के साथ नई समस्याएं भी आती हैं. WebSocket के मामले में, यह प्रॉक्सी सर्वर के साथ काम करता है. ये सर्वर, ज़्यादातर कंपनी नेटवर्क में एचटीटीपी कनेक्शन को मीडिएट करते हैं. WebSocket प्रोटोकॉल, एचटीटीपी कनेक्शन को WebSocket कनेक्शन में 'अपग्रेड' करने के लिए, एचटीटीपी अपग्रेड सिस्टम का इस्तेमाल करता है. आम तौर पर, इसका इस्तेमाल एचटीटीपी/एसएसएल के लिए किया जाता है. कुछ प्रॉक्सी सर्वर को यह पसंद नहीं आता और वे कनेक्शन को ड्रॉप कर देते हैं. इसलिए, अगर कोई क्लाइंट WebSocket प्रोटोकॉल का इस्तेमाल करता है, तो हो सकता है कि कनेक्शन न बन पाए. इसलिए, अगला सेक्शन और भी अहम हो जाता है :)
आज ही WebSockets का इस्तेमाल करें
WebSocket अब भी एक नई टेक्नोलॉजी है और इसे सभी ब्राउज़र में पूरी तरह से लागू नहीं किया गया है. हालांकि, WebSocket का इस्तेमाल आज उन लाइब्रेरी के साथ किया जा सकता है जो ऊपर बताए गए फ़ॉलबैक में से किसी एक का इस्तेमाल करती हैं. ऐसा तब होता है, जब WebSocket उपलब्ध न हो. इस डोमेन में बहुत लोकप्रिय हो चुकी लाइब्रेरी socket.io है, जो प्रोटोकॉल के क्लाइंट और सर्वर लागू करने के साथ आती है. इसमें फ़ॉलबैक भी शामिल हैं (socket.io, फ़रवरी 2012 तक बाइनरी मैसेजिंग के साथ काम नहीं करता). PusherApp जैसे व्यावसायिक समाधान भी मौजूद हैं. इन्हें किसी भी वेब एनवायरमेंट में आसानी से इंटिग्रेट किया जा सकता है. इसके लिए, क्लाइंट को WebSocket मैसेज भेजने के लिए एचटीटीपी एपीआई उपलब्ध कराना होगा. अतिरिक्त एचटीटीपी अनुरोध की वजह से, प्योर WebSocket की तुलना में हमेशा अतिरिक्त ओवरहेड होगा.
सर्वर साइड
WebSocket का इस्तेमाल करने से, सर्वर साइड ऐप्लिकेशन के लिए इस्तेमाल का एक नया पैटर्न बनता है. LAMP जैसे पारंपरिक सर्वर स्टैक, एचटीटीपी अनुरोध/जवाब साइकल के हिसाब से डिज़ाइन किए गए हैं. हालांकि, वे अक्सर बड़ी संख्या में खुले WebSocket कनेक्शन को अच्छी तरह से मैनेज नहीं कर पाते. एक ही समय पर कई कनेक्शन खुले रखने के लिए, ऐसे आर्किटेक्चर की ज़रूरत होती है जो कम परफ़ॉर्मेंस लागत पर ज़्यादा कॉनकरेंसी हासिल कर सके. इस तरह के आर्किटेक्चर को आम तौर पर, थ्रेडिंग या नॉन-ब्लॉकिंग आईओ के हिसाब से डिज़ाइन किया जाता है.
सर्वर साइड पर लागू की गई सेटिंग
- Node.js
- Java
- रूबी
- Python
- Erlang
- C++
- .NET
प्रोटोकॉल के वर्शन
WebSocket के लिए वायर प्रोटोकॉल (क्लाइंट और सर्वर के बीच हैंडशेक और डेटा ट्रांसफ़र) अब RFC6455 है. Chrome और Android के लिए Chrome का सबसे नया वर्शन, RFC6455 के साथ पूरी तरह से काम करता है. इसमें बाइनरी मैसेजिंग भी शामिल है. साथ ही, Firefox का वर्शन 11 और Internet Explorer का वर्शन 10 इस्तेमाल किया जा सकता है. प्रोटोकॉल के पुराने वर्शन अब भी इस्तेमाल किए जा सकते हैं. हालांकि, हमारा सुझाव है कि ऐसा न करें, क्योंकि वे सुरक्षित नहीं होते. अगर आपने WebSocket प्रोटोकॉल के पुराने वर्शन के लिए सर्वर लागू किए हैं, तो हमारा सुझाव है कि आप इसे नए वर्शन पर अपग्रेड करें.
उपयोग के उदाहरण
जब भी आपको क्लाइंट और सर्वर के बीच रीयल टाइम कनेक्शन के करीब, इंतज़ार के समय को कम करना हो, तब WebSocket का इस्तेमाल करें. ध्यान रखें कि इसके लिए, आपको सर्वर साइड ऐप्लिकेशन बनाने के तरीके पर फिर से विचार करना पड़ सकता है. साथ ही, इवेंट सूची जैसी टेक्नोलॉजी पर नए सिरे से ध्यान देना पड़ सकता है. इस्तेमाल के कुछ उदाहरण यहां दिए गए हैं:
- एक से ज़्यादा खिलाड़ियों वाले ऑनलाइन गेम
- चैट ऐप्लिकेशन
- लाइव स्पोर्ट्स टिकर
- रीयल-टाइम में अपडेट होने वाली सोशल स्ट्रीम
डेमो
- Plink
- Paint With Me
- Pixelatr
- डैश वाली
- एक से ज़्यादा खिलाड़ियों वाला ऑनलाइन क्रॉसवर्ड गेम
- पिंग सर्वर (ऊपर दिए गए उदाहरणों में इस्तेमाल किया गया है)
- HTML5demos का सैंपल