एक्शन केबल जैसी लाइब्रेरीज़ के साथ रेल्स में रियल टाइम फीचर्स बनाना बहुत आसान हो गया है। ऐपसिग्नल अकादमी के इस एपिसोड में, हम रियल टाइम अपडेटिंग में गोता लगाएंगे और एक मिनिमल वेबसॉकेट सर्वर बनाने के साथ खिलवाड़ करेंगे ताकि यह देखा जा सके कि हुड के नीचे यह कैसे काम करता है।
हम एक एप्लिकेशन बना रहे होंगे जो डेटा को पुश करता है, और वेबसॉकेट पर पब/सब का उपयोग करता है। कोड शुरू करने से पहले, आइए पहले उन तीन अवधारणाओं के अर्थ को कवर करने में थोड़ा समय बिताते हैं:
पुश डेटा को रिसीवर तक पुश करने को संदर्भित करता है बजाय इसके कि रिसीवर उस डेटा के लिए पोल करे। स्टॉक की कीमतों, चैट एप्लिकेशन्स, या ऑपरेशन्स कंसोल जैसे रियलटाइम अपडेट में एक आवश्यकता।
पब/सब या पब्लिश और सब्सक्राइब डेटा को पुश करने के लिए एक इंटरैक्शन मॉडल है जिसे 1990 के दशक में वॉल स्ट्रीट पर TIBCO द्वारा लोकप्रिय बनाया गया था। एक रिसीवर एक सब्जेक्ट को सब्सक्राइब करता है और पब्लिशर द्वारा उस सब्जेक्ट पर डेटा पुश करने की प्रतीक्षा करता है। पब्लिश्ड मैसेज को लिस्टनर से मिलान करने के लिए वाइल्डकार्ड पैटर्न मिलान शामिल करना आम है, हालांकि कुछ सरल कार्यान्वयन केवल सब्जेक्ट में वाइल्डकार्ड्स के बजाय नामित चैनलों का उपयोग करते हैं। मैं उन शुरुआती दिनों में TIBCO पर शुरू हुआ था इसलिए मुझे वाइल्डकार्ड पैटर्न मिलान का लचीलापन पसंद है।
वेबसॉकेट डेटा एक्सचेंज के लिए एक प्रोटोकॉल है - आमतौर पर एक वेब ब्राउज़र और एक एप्लिकेशन के बीच। एक HTTP कनेक्शन को वेबसॉकेट कनेक्शन में अपग्रेड किया जाता है और फिर दो एंडपॉइंट्स के बीच दोनों तरफ डेटा भेजा जा सकता है। वेबसॉकेट्स एप्लिकेशन से ब्राउज़र में डेटा पुश कर सकते हैं। यह आपके ब्राउज़र में जावास्क्रिप्ट कोड से एप्लिकेशन में डेटा वापस भेजने के लिए POST या PUT के अलावा एक और तंत्र प्रदान करता है। बहुत अच्छा, है ना?
हुड के नीचे
आइए देखें कि वेबसॉकेट सर्वर का एक उदाहरण कैसे काम कर सकता है। ब्राउज़र से, क्लाइंट जावास्क्रिप्ट कोड के साथ सर्वर से वेबसॉकेट कनेक्शन बनाने का प्रयास करता है।
var sock = new WebSocket("ws://" + document.URL.split("/")[2] + "/upgrade");
सर्वर एक HTTP अनुरोध प्राप्त करता है जिसमें एक संकेतक होता है कि अपग्रेड का अनुरोध किया गया था। आमतौर पर, सर्वर एप्लिकेशन को यह तय करने देता है कि अपग्रेड करना है या नहीं। यह कैसे करता है यह एप्लिकेशन को प्रदान किए गए API पर निर्भर करता है। एक सर्वर जो Rack का समर्थन करता है, सॉकेट को हाईजैक करने और डेवलपर को सभी प्रोटोकॉल विवरणों को संभालने देने का विकल्प प्रदान करता है या, एक प्रस्तावित PR के अनुसार, अपग्रेड करने के लिए एक प्रतिक्रिया पर्याप्त है।
अपग्रेड सर्वर और क्लाइंट के बीच एक्सचेंज का एक सेट है। सभी ब्राउज़र और कुछ सर्वर जेम्स इन विवरणों को छिपाते हैं। एक बार कनेक्शन स्थापित हो जाने पर, वेबसॉकेट प्रोटोकॉल का पालन करते हुए मैसेजेस का आदान-प्रदान किया जा सकता है।
हुड के नीचे का जादू एन्कोडिंग, डिकोडिंग, और मैसेज एक्सचेंज प्रोटोकॉल को संभालता है। मैसेजेस बाइनरी, फिक्स्ड-विड्थ संरचनाएं हैं जिनमें ट्रेलिंग पेलोड होता है, जिसे SHA1 का उपयोग करके एन्क्रिप्ट किया जाता है। वेबसॉकेट प्रोटोकॉल में कई मैसेज टाइप्स और एक्सचेंज शामिल हैं, जैसे पिंग/पॉन्ग हार्टबीट्स और ओपनिंग और क्लोजिंग मैसेज एक्सचेंज। वह जादू है जो सर्वर कनेक्शन-हाईजैक दृष्टिकोण का उपयोग नहीं करके करते हैं।
गोता लगाना
हम एक क्लॉक थ्रेड के उदाहरण का उपयोग करेंगे जो सभी सुनने वाले क्लाइंट्स को वर्तमान समय प्रकाशित करने के लिए शुरू किया जाता है। हम अपने सर्वर के निर्माण के लिए Agoo का उपयोग करेंगे क्योंकि यह तेज़ है और जटिलता को न्यूनतम रखता है।
हम कुछ जावास्क्रिप्ट के साथ क्लाइंट के रूप में शुरू करेंगे जो एक HTML पेज पर वर्तमान समय दिखाता है। एक नया WebSocket बनाने के बाद एक onopen कॉलबैक सेट किया जाता है जो स्टेटस HTML एलिमेंट को बदलता है। onmessage कॉलबैक message HTML एलिमेंट को अपडेट करता है। कॉलबैक्स पब्लिश और सब्सक्राइब एक्सचेंज जैसे एसिंक्रोनस कॉल्स के साथ काम करते समय एक सामान्य डिज़ाइन पैटर्न है।
<!-- websocket.html -->
<html>
<body>
<p id="status">...</p>
<p id="message">... waiting ...</p>
<script type="text/javascript">
var sock = new WebSocket(
"ws://" + document.URL.split("/")[2] + "/upgrade"
);
sock.onopen = function () {
document.getElementById("status").textContent = "connected";
};
sock.onmessage = function (msg) {
document.getElementById("message").textContent = msg.data;
};
</script>
</body>
</html>
हमारा क्लाइंट हो जाने के बाद, आइए सर्वर को लागू करें, जो Rack API का उपयोग करने वाला एक रूबी एप्लिकेशन है। Clock क्लास स्वयं /upgrade पथ पर सभी HTTP अनुरोधों के लिए एक हैंडलर होगा। यदि अनुरोध अपग्रेड के लिए है तो हम केवल सक्सेस लौटाते हैं HTTP स्टेटस कोड 200 के साथ, अन्यथा, हम पेज नॉट फाउंड के लिए 404 लौटाते हैं। #call मेथड में केवल अन्य चरण वेबसॉकेट हैंडलर का असाइनमेंट है।
class Clock
def self.call(env)
unless env['rack.upgrade?'].nil?
env['rack.upgrade'] = Clock
[ 200, { }, [ ] ]
else
[ 404, { }, [ ] ]
end
end
end
API कॉलबैक्स पर आधारित है। हमारे सर्वर के लिए हम जिस एकमात्र कॉलबैक की परवाह करते हैं वह #on_open कॉलबैक है जो हमें "time" सब्जेक्ट की सदस्यता बनाने में सक्षम बनाता है। मैसेजेस सब्जेक्ट्स या टॉपिक्स द्वारा पहचाने गए चैनलों पर एक्सचेंज किए जाते हैं। #on_open तब कहा जाता है जब एक वेबसॉकेट कनेक्शन स्थापित होता है।
class Clock
# ...
def self.on_open(client)
client.subscribe('time')
end
end
अब, आइए एक थ्रेड के साथ पब्लिशिंग शुरू करें जो हर सेकंड के बाद समय प्रकाशित करता है। Agoo.publish की कॉल "time" सब्जेक्ट पर एक मैसेज भेजती है, फिर सभी सब्सक्राइबर्स मैसेज प्राप्त करते हैं। सर्वर सब्सक्रिप्शन्स और कनेक्शन्स को ट्रैक करता है और मैसेज को जावास्क्रिप्ट क्लाइंट तक पहुंचाता है जो HTML एलिमेंट को अपडेट करता है।
require 'agoo'
Thread.new {
loop do
now = Time.now
Agoo.publish('time', "%02d:%02d:%02d" % [now.hour, now.min, now.sec])
sleep(1)
end
}
आवश्यक एकमात्र अन्य कोड वह कोड है जो सर्वर को इनिशियलाइज़ और शुरू करता है। Agoo::Server.handle(:GET, '/upgrade', Clock) की कॉल सर्वर को /upgrade URL पथ पर HTTP GET अनुरोधों को सुनने और उन अनुरोधों को Clock क्लास में पास करने के लिए कहती है। यह रूटिंग को रूबी के बाहर होने की अनुमति देता है जिससे प्रदर्शन और लचीलापन में सुधार होता है।
Agoo::Server.init(6464, '.', thread_count: 0)
Agoo::Server.handle(:GET, '/upgrade', Clock)
Agoo::Server.start
हम लगभग वहां हैं। सर्वर को इस कमांड के साथ चलाएं।
$ ruby pubsub.rb
एक लॉग एंट्री दिखाई देनी चाहिए जिसमें निम्न जैसा कुछ दिखे, जो दर्शाता है कि सर्वर चल रहा है और पोर्ट 6464 पर सुन रहा है।
I 2018/08/14 19:49:45.170618000 INFO: Agoo 2.5.0 with pid 40366 is listening on https://:6464.
यह देखने का समय कि क्या यह काम कर रहा है
आइए https://localhost:6464/websocket.html खोलें। कनेक्शन स्थापित होने पर एक प्रारंभिक झिलमिलाहट के बाद, कनेक्शन स्टेटस और समय प्रदर्शित होना चाहिए। समय हर सेकंड बढ़ेगा जैसे ही क्लॉक टिकेगी।
connected
19:50:12
पब्लिश और सब्सक्राइब वेब एप्लिकेशन बनाने पर बधाई ;-)
आज के एपिसोड में, हमने वेबसॉकेट का उपयोग करने पर ध्यान दिया। सर्वर सेंट इवेंट्स (SSE) वही करने का एक और विकल्प प्रदान करता है, और हमने पूर्ण स्रोत कोड उदाहरण में SSE शामिल किया है। यदि आप अधिक जानना चाहते हैं, तो हमारे द्वारा उपयोग किए गए Agoo सर्वर या आयोडीन वेबसॉकेट सर्वर पर एक नज़र डालें।
यदि आपके कोई प्रश्न या टिप्पणियां हैं, तो @AppSignal पर हमें एक लाइन लिखने में संकोच न करें।