समस्या: क्लाइंट-सर्वर और सर्वर-क्लाइंट कनेक्शन में कम इंतज़ार
वेब का मुख्य रूप से निर्माण, एचटीटीपी के तथाकथित अनुरोध/जवाब वाले मॉडल के आधार पर किया गया है. क्लाइंट, वेब पेज को लोड करता है. इसके बाद, जब तक उपयोगकर्ता अगले पेज पर क्लिक नहीं करता, तब तक कुछ नहीं होता. साल 2005 के आस-पास, AJAX ने वेब को ज़्यादा डाइनैमिक बनाने का काम शुरू किया. हालांकि, सभी एचटीटीपी कम्यूनिकेशन को क्लाइंट से कंट्रोल किया जाता था. इसके लिए, सर्वर से नया डेटा लोड करने के लिए, उपयोगकर्ता के इंटरैक्शन या समय-समय पर पोलिंग की ज़रूरत होती थी.
ऐसी टेक्नोलॉजी जो सर्वर को क्लाइंट को डेटा भेजने की सुविधा देती हैं, वे काफी समय से मौजूद हैं. ये टेक्नोलॉजी, सर्वर को उसी समय क्लाइंट को डेटा भेजने की सुविधा देती हैं, जब उसे पता चलता है कि नया डेटा उपलब्ध है. इन्हें 'पुश' या 'कॉमेट' जैसे नामों से जाना जाता है. सर्वर से शुरू किए गए कनेक्शन का भ्रम पैदा करने के लिए, सबसे ज़्यादा इस्तेमाल होने वाले हैक में से एक को लॉन्ग पोलिंग कहा जाता है. लॉन्ग पोलिंग की मदद से, क्लाइंट सर्वर के साथ एचटीटीपी कनेक्शन खोलता है. यह कनेक्शन, जवाब मिलने तक खुला रहता है. जब भी सर्वर में नया डेटा होता है, तब वह जवाब भेजता है. अन्य तकनीकों में Flash, XHR मल्टीपार्ट अनुरोध, और htmlfiles शामिल हैं. लंबी अवधि के पोल कराने की सुविधा और अन्य तकनीकें काफ़ी कारगर हैं. इनका इस्तेमाल हर दिन, GMail Chat जैसे ऐप्लिकेशन में किया जाता है.
हालांकि, इन सभी समाधान में एक समस्या होती है: ये एचटीटीपी का ऊपरी हिस्सा होते हैं, जो उन्हें कम प्रतीक्षा अवधि वाले ऐप्लिकेशन के लिए सही नहीं बनाते. ब्राउज़र या किसी अन्य ऑनलाइन गेम में रीयलटाइम कॉम्पोनेंट के साथ, एक से ज़्यादा खिलाड़ियों वाले फ़र्स्ट पर्सन शूटर गेम के बारे में सोचें.
पेश है WebSocket: वेब पर सॉकेट की सुविधा
WebSocket स्पेसिफ़िकेशन, वेब ब्राउज़र और सर्वर के बीच "सॉकेट" कनेक्शन बनाने वाले एपीआई के बारे में बताता है. आसान शब्दों में: क्लाइंट और सर्वर के बीच एक स्थायी कनेक्शन होता है और दोनों पक्ष किसी भी समय डेटा भेजना शुरू कर सकते हैं.
शुरू करें
WebSocket कनेक्शन खोलने के लिए, WebSocket कन्स्ट्रक्टर को कॉल करें:
var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);
ws:
पर ध्यान दें. यह 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 ऑब्जेक्ट की एक्सटेंशन प्रॉपर्टी की जांच करके, सर्वर से स्वीकार किए जाने वाले एक्सटेंशन देखे जा सकते हैं. फ़रवरी 2012 तक, एक्सटेंशन के लिए आधिकारिक तौर पर कोई स्पेसिफ़िकेशन पब्लिश नहीं किया गया है.
// Determining accepted extensions
console.log(connection.extensions);
क्रॉस-ऑरिजिन कम्यूनिकेशन
यह एक आधुनिक प्रोटोकॉल है. इसमें क्रॉस-ऑरिजिन कम्यूनिकेशन की सुविधा पहले से मौजूद होती है. आपको अब भी यह पक्का करना चाहिए कि आप सिर्फ़ उन क्लाइंट और सर्वर से कम्यूनिकेट करें जिन पर आपको भरोसा है. हालांकि, वेबसोकेट की मदद से किसी भी डोमेन पर, दोनों पक्षों के बीच कम्यूनिकेशन किया जा सकता है. सर्वर यह तय करता है कि उसकी सेवा सभी क्लाइंट के लिए उपलब्ध कराई जाए या सिर्फ़ उन क्लाइंट के लिए जो अच्छी तरह से तय किए गए डोमेन के सेट पर मौजूद हैं.
प्रॉक्सी सर्वर
हर नई टेक्नोलॉजी के साथ नई समस्याएं भी आती हैं. वेबसोकेट के मामले में, यह प्रॉक्सी सर्वर के साथ काम करने की सुविधा है, जो ज़्यादातर कंपनी नेटवर्क में एचटीटीपी कनेक्शन को मीडिएट करता है. WebSocket प्रोटोकॉल, एचटीटीपी कनेक्शन को WebSocket कनेक्शन में 'अपग्रेड' करने के लिए, एचटीटीपी अपग्रेड सिस्टम (जिसका इस्तेमाल आम तौर पर एचटीटीपी/एसएसएल के लिए किया जाता है) का इस्तेमाल करता है. कुछ प्रॉक्सी सर्वर को यह पसंद नहीं होता और वे कनेक्शन छोड़ देंगे. इसलिए, भले ही कोई क्लाइंट WebSocket प्रोटोकॉल का इस्तेमाल करता हो, लेकिन हो सकता है कि वह कनेक्शन न बना पाए. इससे अगले सेक्शन की अहमियत और भी बढ़ जाती है :)
WebSockets का इस्तेमाल आज ही करें
WebSocket अभी एक नई टेक्नोलॉजी है और इसे सभी ब्राउज़र में पूरी तरह से लागू नहीं किया गया है. हालांकि, WebSocket उपलब्ध न होने पर, ऊपर बताए गए फ़ॉलबैक में से किसी एक का इस्तेमाल करने वाली लाइब्रेरी के साथ, WebSocket का इस्तेमाल किया जा सकता है. इस डोमेन में socket.io लाइब्रेरी काफ़ी लोकप्रिय हो गई है. यह प्रोटोकॉल के क्लाइंट और सर्वर के साथ आती है. साथ ही, इसमें फ़ॉलबैक भी शामिल होते हैं. फ़रवरी 2012 तक, socket.io बाइनरी मैसेजिंग के साथ काम नहीं करता था. PusherApp जैसे कारोबारी समाधान भी मौजूद हैं. इन्हें क्लाइंट को WebSocket मैसेज भेजने के लिए एचटीटीपी एपीआई देकर, किसी भी वेब एनवायरमेंट में आसानी से इंटिग्रेट किया जा सकता है. अतिरिक्त एचटीटीपी अनुरोध की वजह से, WebSocket की तुलना में हमेशा अतिरिक्त ओवरहेड होगा.
सर्वर साइड
WebSocket का इस्तेमाल करने से, सर्वर साइड ऐप्लिकेशन के इस्तेमाल का एक नया पैटर्न बनता है. LAMP जैसे पारंपरिक सर्वर स्टैक, एचटीटीपी अनुरोध/रिस्पॉन्स साइकल के हिसाब से डिज़ाइन किए गए हैं. हालांकि, वे अक्सर बड़ी संख्या में ओपन WebSocket कनेक्शन के साथ ठीक से काम नहीं करते. एक ही समय पर कई कनेक्शन खुले रखने के लिए, ऐसे आर्किटेक्चर की ज़रूरत होती है जो कम परफ़ॉर्मेंस लागत पर ज़्यादा कंसिस्टेंसी पाता हो. ऐसे आर्किटेक्चर आम तौर पर, थ्रेडिंग या इन्हें ब्लॉक न करने वाला IO कहा जाता है.
सर्वर साइड पर लागू करना
- Node.js
- Java
- Ruby
- Python
- Erlang
- C++
- .NET
प्रोटोकॉल के वर्शन
WebSocket के लिए, वायर प्रोटोकॉल (हैंडशेक और क्लाइंट और सर्वर के बीच डेटा ट्रांसफ़र) अब RFC6455 है. Chrome का नया वर्शन और Android के लिए Chrome, आरएफ़सी6455 के साथ पूरी तरह से काम करते हैं. इसमें बाइनरी मैसेजिंग भी शामिल है. साथ ही, Firefox 11 और Internet Explorer 10 के साथ भी यह काम करेगा. प्रोटोकॉल के पुराने वर्शन अब भी इस्तेमाल किए जा सकते हैं. हालांकि, हमारा सुझाव है कि ऐसा न करें, क्योंकि ये असुरक्षित हैं. अगर आपने WebSocket प्रोटोकॉल के पुराने वर्शन के लिए सर्वर लागू किए हैं, तो हमारा सुझाव है कि आप उन्हें नए वर्शन पर अपग्रेड करें.
उपयोग के उदाहरण
जब आपको क्लाइंट और सर्वर के बीच कम इंतज़ार वाला और रीयल-टाइम जैसा कनेक्शन चाहिए, तब WebSocket का इस्तेमाल करें. ध्यान रखें कि इवेंट की सूची जैसी टेक्नोलॉजी पर नए फ़ोकस के साथ, सर्वर साइड ऐप्लिकेशन बनाने के तरीके में बदलाव करना पड़ सकता है. इस्तेमाल के कुछ उदाहरण यहां दिए गए हैं:
- एक से ज़्यादा खिलाड़ी वाले ऑनलाइन गेम
- चैट ऐप्लिकेशन
- लाइव स्पोर्ट्स टिकर
- रीयल टाइम अपडेट होने वाली सोशल मीडिया स्ट्रीम
डेमो
- Plink
- Paint With Me
- Pixelatr
- डैश किया गया
- एक से ज़्यादा खिलाड़ी वाले ऑनलाइन क्रॉसवर्ड गेम
- पिंग सर्वर (ऊपर दिए गए उदाहरणों में इस्तेमाल किया गया)
- HTML5demos का सैंपल