पब्लिश करने की तारीख: 04 नवंबर, 2013
WebRTC की मदद से, पीयर-टू-पीयर कम्यूनिकेशन किया जा सकता है. इसके लिए सर्वर की ज़रूरत होती है, ताकि क्लाइंट, मेटाडेटा शेयर कर सकें और सिग्नलिंग नाम की प्रोसेस के ज़रिए कम्यूनिकेशन को मैनेज कर सकें. सर्वर, क्लाइंट को नेटवर्क अड्रेस ट्रांसलेटर (NAT) और फ़ायरवॉल से निपटने में भी मदद करते हैं.
यहां आपको सिग्नल सेवा बनाने और STUN और TURN सर्वर के साथ रीयल-वर्ल्ड कनेक्टिविटी की समस्याओं से निपटने का तरीका बताया गया है. आपको यह भी पता चलेगा कि WebRTC ऐप्लिकेशन, एक से ज़्यादा लोगों के साथ होने वाले कॉल को कैसे मैनेज कर सकते हैं. साथ ही, वीओआईपी और पीएसटीएन (इन्हें टेलीफ़ोन भी कहा जाता है) जैसी सेवाओं के साथ कैसे इंटरैक्ट कर सकते हैं.
सिग्नलिंग क्या है?
सिग्नलिंग, बातचीत को कोऑर्डिनेट करने की प्रोसेस है. WebRTC ऐप्लिकेशन को कॉल सेट अप करने के लिए, उसके क्लाइंट को यह जानकारी शेयर करनी होगी:
- सेशन-कंट्रोल मैसेज, जिनका इस्तेमाल बातचीत शुरू करने या खत्म करने के लिए किया जाता है
- गड़बड़ी के मैसेज
- मीडिया मेटाडेटा, जैसे कि कोडेक, कोडेक सेटिंग, बैंडविड्थ, और मीडिया टाइप
- सुरक्षित कनेक्शन बनाने के लिए इस्तेमाल किया जाने वाला मुख्य डेटा
- नेटवर्क डेटा, जैसे कि होस्ट का आईपी पता और पोर्ट, जैसा कि बाहरी दुनिया को दिखता है
सिग्नल भेजने की इस प्रोसेस के लिए, क्लाइंट को मैसेज भेजने और पाने का तरीका चाहिए. WebRTC API, इस तरीके को लागू नहीं करते. इसके बजाय, आपको इसे खुद बनाना होगा.
WebRTC में सिग्नलिंग को क्यों नहीं तय किया गया है?
WebRTC के स्टैंडर्ड में, सिग्नल भेजने के तरीकों और प्रोटोकॉल के बारे में नहीं बताया गया है. ऐसा इसलिए किया गया है, ताकि डेटा को बार-बार भेजने से बचा जा सके और पहले से मौजूद टेक्नोलॉजी के साथ ज़्यादा से ज़्यादा काम किया जा सके. इस तरीके के बारे में, JavaScript Session Establishment Protocol (जेएसईपी) में बताया गया है:
जेएसईपी का आर्किटेक्चर, ब्राउज़र को स्टेट सेव करने से भी रोकता है. इसका मतलब है कि यह सिग्नल देने वाली स्टेट मशीन के तौर पर काम करता है. उदाहरण के लिए, अगर पेज को फिर से लोड करने पर हर बार सिग्नल डेटा मिट जाता है, तो इससे समस्या हो सकती है. इसके बजाय, सिग्नल की स्थिति को सर्वर पर सेव किया जा सकता है.
जेएसईपी को पीयर के बीच ऑफ़र और जवाब, मीडिया मेटाडेटा के एक्सचेंज की ज़रूरत होती है. ऑफ़र और जवाब, सेशन डिस्क्रिप्शन प्रोटोकॉल (एसडीपी) फ़ॉर्मैट में भेजे जाते हैं. यह कुछ ऐसा दिखता है:
v=0
o=- 7614219274584779017 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:W2TGCZw2NZHuwlnf
a=ice-pwd:xdQEccP40E+P0L5qTyzDgfmW
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:9c1AHz27dZ9xPI91YNfSlI67/EMkjHHIHORiClQe
a=rtpmap:111 opus/48000/2
...
क्या आपको जानना है कि एसडीपी के इस मुश्किल कोड का असल में क्या मतलब है? इंटरनेट इंजीनियरिंग टास्क फ़ोर्स (आईईटीएफ़) के उदाहरण देखें.
ध्यान रखें कि WebRTC को इस तरह से डिज़ाइन किया गया है कि एसडीपी टेक्स्ट में वैल्यू में बदलाव करके, ऑफ़र या जवाब को लोकल या रिमोट ब्यौरे के तौर पर सेट करने से पहले, उसमें बदलाव किया जा सकता है. उदाहरण के लिए, appr.tc में preferAudioCodec() फ़ंक्शन का इस्तेमाल करके, डिफ़ॉल्ट कोडेक और बिटरेट सेट किया जा सकता है. JavaScript की मदद से एसडीपी में बदलाव करना थोड़ा मुश्किल है. इस बारे में चर्चा चल रही है कि क्या WebRTC के आने वाले वर्शन में, एसडीपी के बजाय JSON का इस्तेमाल किया जाना चाहिए. हालांकि, एसडीपी का इस्तेमाल जारी रखने के कुछ फ़ायदे हैं.
RTCPeerConnection एपीआई और सिग्नल: ऑफ़र, जवाब, और कैंडिडेट
RTCPeerConnection एक ऐसा एपीआई है जिसका इस्तेमाल WebRTC ऐप्लिकेशन, पीयर के बीच कनेक्शन बनाने और ऑडियो और वीडियो कम्यूनिकेट करने के लिए करते हैं.
इस प्रोसेस को शुरू करने के लिए, RTCPeerConnection को दो काम करने होंगे:
- लोकल मीडिया की स्थितियों का पता लगाएं. जैसे, रिज़ॉल्यूशन और कोडेक की क्षमताएं. यह वह मेटाडेटा है जिसका इस्तेमाल, ऑफ़र-ऐंड-आंसर मैकेनिज़्म के लिए किया जाता है.
- ऐप्लिकेशन के होस्ट के लिए संभावित नेटवर्क पते पाना. इन्हें कैंडिडेट कहा जाता है.
इस स्थानीय डेटा की पुष्टि होने के बाद, इसे सिग्नल देने वाले तरीके से रिमोट पीयर के साथ शेयर किया जाना चाहिए.
मान लें कि ऐलिस, ईव को कॉल करने की कोशिश कर रही है. यहां कॉल का जवाब देने के तरीके के बारे में पूरी जानकारी दी गई है:
- ऐलिस ने
RTCPeerConnectionऑब्जेक्ट बनाया. - गुंजन,
RTCPeerConnectioncreateOffer()तरीके का इस्तेमाल करके एक ऑफ़र (एसडीपी सेशन की जानकारी) बनाती है. - ऐलिस,
setLocalDescription()को कॉल करके अपना ऑफ़र बताती है. - ऐलिस, ऑफ़र को स्ट्रिंग में बदलती है और उसे ईव को भेजने के लिए, सिग्नल भेजने के तरीके का इस्तेमाल करती है.
- ईव, ऐलिस के ऑफ़र के साथ
setRemoteDescription()को कॉल करती है, ताकि उसकेRTCPeerConnectionको ऐलिस के सेटअप के बारे में पता चल सके. - ईव
createAnswer()को कॉल करती है और इसके लिए सक्सेस कॉलबैक, लोकल सेशन की जानकारी को पास करता है - ईव का जवाब. - ईव,
setLocalDescription()को कॉल करके, अपने जवाब को स्थानीय भाषा में जानकारी के तौर पर सेट करती है. - इसके बाद, ईव सिग्नल भेजने के तरीके का इस्तेमाल करके, ऐलिस को स्ट्रिंग में बदला गया जवाब भेजती है.
- एलिस,
setRemoteDescription()का इस्तेमाल करके ईव के जवाब को रिमोट सेशन के ब्यौरे के तौर पर सेट करती है.
ऐलिस और ईव को भी नेटवर्क की जानकारी शेयर करनी होगी. "उम्मीदवारों को ढूंढना" वाक्यांश का मतलब, ICE फ़्रेमवर्क का इस्तेमाल करके नेटवर्क इंटरफ़ेस और पोर्ट ढूंढने की प्रोसेस से है.
- ऐलिस,
onicecandidateहैंडलर के साथ एकRTCPeerConnectionऑब्जेक्ट बनाती है. - नेटवर्क कैंडिडेट उपलब्ध होने पर, हैंडलर को कॉल किया जाता है.
- हैंडलर में, ऐलिस अपने सिग्नलिंग चैनल के ज़रिए ईव को स्ट्रिंगिफ़ाइड कैंडिडेट डेटा भेजती है.
- जब ईव को ऐलिस से कैंडिडेट मैसेज मिलता है, तो वह
addIceCandidate()को कॉल करती है, ताकि कैंडिडेट को रिमोट पीयर की जानकारी में जोड़ा जा सके.
जेएसईपी, आईसीई कैंडिडेट ट्रिकलिंग के साथ काम करता है. इससे कॉल करने वाला व्यक्ति, शुरुआती ऑफ़र के बाद कॉल पाने वाले व्यक्ति को धीरे-धीरे कैंडिडेट उपलब्ध करा सकता है. साथ ही, कॉल पाने वाला व्यक्ति, सभी कैंडिडेट के आने का इंतज़ार किए बिना, कॉल पर कार्रवाई शुरू कर सकता है और कनेक्शन सेट अप कर सकता है.
सिग्नलिंग के लिए WebRTC कोड
यहां दिया गया कोड स्निपेट, W3C कोड का एक उदाहरण है. इसमें सिग्नल भेजने की पूरी प्रोसेस के बारे में बताया गया है. कोड यह मानकर चलता है कि सिग्नल देने का कोई तरीका मौजूद है, SignalingChannel. सिग्नल के बारे में ज़्यादा जानकारी आगे दी गई है.
// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription(await pc.createOffer());
// send the offer to the other peer
signaling.send({desc: pc.localDescription});
} catch (err) {
console.error(err);
}
};
// After remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
// Don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = event.streams[0];
};
// Call start() to initiate.
async function start() {
try {
// Get local stream, show it in self-view, and add it to be sent.
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({desc, candidate}) => {
try {
if (desc) {
// If you get an offer, you need to reply with an answer.
if (desc.type === 'offer') {
await pc.setRemoteDescription(desc);
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
await pc.setLocalDescription(await pc.createAnswer());
signaling.send({desc: pc.localDescription});
} else if (desc.type === 'answer') {
await pc.setRemoteDescription(desc);
} else {
console.log('Unsupported SDP type.');
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
ऑफ़र-जवाब और कैंडिडेट-एक्सचेंज की प्रोसेस को काम करते हुए देखने के लिए, simpl.info RTCPeerConnection पर जाएं. साथ ही, सिंगल-पेज वीडियो चैट के उदाहरण के लिए, कंसोल लॉग देखें. Google Chrome में about://webrtc-internals पेज या Opera में opera://webrtc-internals पेज से, WebRTC सिग्नल और आंकड़ों का पूरा डंप डाउनलोड किया जा सकता है.
आस-पास मौजूद डिवाइसों को ढूंढने की सुविधा
यह सवाल पूछने का एक फै़ंसी तरीका है, "मैं बात करने के लिए किसी को कैसे ढूंढूं?"
टेलीफ़ोन कॉल के लिए, आपके पास टेलीफ़ोन नंबर और डायरेक्ट्री होती हैं. ऑनलाइन वीडियो चैट और मैसेजिंग के लिए, आपको पहचान और मौजूदगी को मैनेज करने वाले सिस्टम की ज़रूरत होती है. साथ ही, उपयोगकर्ताओं के लिए सेशन शुरू करने का कोई ज़रिया होना चाहिए. WebRTC ऐप्लिकेशन को एक ऐसा तरीका चाहिए जिससे क्लाइंट एक-दूसरे को सिग्नल भेज सकें कि उन्हें कॉल शुरू करना है या उसमें शामिल होना है.
WebRTC, पीयर डिस्कवरी के तरीकों के बारे में नहीं बताता. साथ ही, आपको यहां दिए गए विकल्पों को देखने की ज़रूरत नहीं है. यह प्रोसेस, किसी यूआरएल को ईमेल या मैसेज करने जितनी आसान हो सकती है. Talky, tawk.to, और Browser Meeting जैसे वीडियो चैट ऐप्लिकेशन के लिए, लोगों को कॉल में शामिल होने का न्योता देने के लिए, कस्टम लिंक शेयर किया जाता है. डेवलपर क्रिस बॉल ने एक दिलचस्प serverless-webrtc एक्सपेरिमेंट किया. इससे WebRTC कॉल में हिस्सा लेने वाले लोग, अपनी पसंद की किसी भी मैसेज सेवा का इस्तेमाल करके मेटाडेटा शेयर कर सकते हैं. जैसे, आईएम, ईमेल या हो मिंग पिजन.
सिग्नलिंग सेवा कैसे बनाई जा सकती है?
हम फिर से बता दें कि WebRTC के स्टैंडर्ड, सिग्नल प्रोटोकॉल और मैकेनिज़्म तय नहीं करते. आप जो भी चुनें, आपको क्लाइंट के बीच सिग्नल मैसेज और ऐप्लिकेशन का डेटा एक्सचेंज करने के लिए, एक इंटरमीडियरी सर्वर की ज़रूरत होगी. अफ़सोस, कोई वेब ऐप्लिकेशन इंटरनेट पर चिल्लाकर यह नहीं कह सकता, "मुझे मेरे दोस्त से कनेक्ट करो!"
अच्छी बात यह है कि सिग्नलिंग मैसेज छोटे होते हैं और ज़्यादातर कॉल की शुरुआत में ही एक्सचेंज किए जाते हैं. वीडियो चैट सेशन के लिए appr.tc की मदद से की गई टेस्टिंग में, सिग्नल सेवा ने कुल 30 से 45 मैसेज मैनेज किए. इन सभी मैसेज का कुल साइज़ करीब 10 केबी था.
बैंडविड्थ के मामले में कम मांग होने के साथ-साथ, WebRTC सिग्नलिंग सेवाएं ज़्यादा प्रोसेसिंग या मेमोरी का इस्तेमाल नहीं करती हैं. ऐसा इसलिए, क्योंकि उन्हें सिर्फ़ मैसेज रिले करने और सेशन की स्थिति का थोड़ा सा डेटा सेव रखने की ज़रूरत होती है. जैसे, कौनसे क्लाइंट कनेक्ट हैं.
सर्वर से क्लाइंट को पुश मैसेज भेजना
सिग्नल भेजने के लिए, मैसेज सेवा का दोनों तरफ़ से काम करना ज़रूरी है: क्लाइंट-टू-सर्वर और सर्वर-टू-क्लाइंट. दोनों तरफ़ से होने वाला कम्यूनिकेशन, एचटीटीपी क्लाइंट/सर्वर के अनुरोध/जवाब वाले मॉडल के ख़िलाफ़ है. हालांकि, वेब सर्वर पर चल रही किसी सेवा से ब्राउज़र में चल रहे वेब ऐप्लिकेशन पर डेटा भेजने के लिए, कई सालों से लॉन्ग पोलिंग जैसे कई हैक डेवलप किए गए हैं.
EventSource एपीआई, सर्वर से भेजे गए इवेंट को चालू करता है. यह डेटा, एचटीटीपी के ज़रिए वेब सर्वर से ब्राउज़र क्लाइंट को भेजा जाता है. EventSource को एकतरफ़ा मैसेजिंग के लिए डिज़ाइन किया गया है. हालांकि, इसका इस्तेमाल XHR के साथ करके, सिग्नल वाले मैसेज भेजने और पाने की सेवा बनाई जा सकती है. सिग्नल देने वाली सेवा, कॉल करने वाले व्यक्ति का मैसेज, कॉल पाने वाले व्यक्ति तक पहुंचाती है. इसके लिए, वह XHR अनुरोध का इस्तेमाल करती है. यह अनुरोध, EventSource के ज़रिए भेजा जाता है.
WebSocket को फ़ुल डुप्लेक्स क्लाइंट-सर्वर कम्यूनिकेशन के लिए डिज़ाइन किया गया है. इसका मतलब है कि मैसेज एक ही समय पर दोनों दिशाओं में भेजे जा सकते हैं. सिर्फ़ WebSocket या सर्वर से भेजे गए इवेंट (EventSource) की मदद से बनाई गई सिग्नल सेवा का एक फ़ायदा यह है कि इन एपीआई के बैकएंड को कई तरह के वेब फ़्रेमवर्क पर लागू किया जा सकता है. ये फ़्रेमवर्क, PHP, Python, और Ruby जैसी भाषाओं के लिए ज़्यादातर वेब-होस्टिंग पैकेज में आम तौर पर इस्तेमाल किए जाते हैं.
WebRTC के साथ काम करने वाले सभी ब्राउज़र, WebSocket के साथ भी काम करते हैं. सभी कनेक्शन के लिए TLS का इस्तेमाल किया जाना चाहिए, ताकि यह पक्का किया जा सके कि मैसेज को एन्क्रिप्ट (सुरक्षित) किए बिना इंटरसेप्ट न किया जा सके. साथ ही, प्रॉक्सी ट्रैवर्सल से जुड़ी समस्याएं कम की जा सकें. WebSocket और प्रॉक्सी ट्रैवर्सल के बारे में ज़्यादा जानकारी के लिए, इल्या ग्रिगोरिक की हाई परफ़ॉर्मेंस ब्राउज़र नेटवर्किंग में WebRTC चैप्टर पढ़ें.
सिग्नल को मैनेज करने के लिए, WebRTC क्लाइंट को Ajax के ज़रिए किसी मैसेजिंग सर्वर को बार-बार पोल करने के लिए कहा जा सकता है. हालांकि, इससे नेटवर्क के कई ग़ैर-ज़रूरी अनुरोध जनरेट होते हैं. यह समस्या खास तौर पर मोबाइल डिवाइसों के लिए होती है. सेशन शुरू होने के बाद भी, पीयर को सिग्नल मैसेज के लिए पोल करना होगा. ऐसा तब करना होगा, जब अन्य पीयर ने सेशन में बदलाव किया हो या उसे खत्म कर दिया हो. WebRTC Book ऐप्लिकेशन के उदाहरण में, पोलिंग फ़्रीक्वेंसी के लिए कुछ ऑप्टिमाइज़ेशन के साथ यह विकल्प चुना गया है.
स्केल सिग्नलिंग
सिग्नल सेवा, हर क्लाइंट के लिए कम बैंडविड्थ और सीपीयू का इस्तेमाल करती है. हालांकि, किसी लोकप्रिय ऐप्लिकेशन के सिग्नल सर्वर को अलग-अलग जगहों से आने वाले बहुत सारे मैसेज को एक साथ हैंडल करना पड़ सकता है. जिन WebRTC ऐप्लिकेशन पर ज़्यादा ट्रैफ़िक आता है उन्हें सिग्नलिंग सर्वर की ज़रूरत होती है, ताकि वे ज़्यादा लोड को मैनेज कर सकें. हम यहां ज़्यादा जानकारी नहीं दे रहे हैं, लेकिन ज़्यादा संख्या में और बेहतर परफ़ॉर्मेंस वाले मैसेज भेजने के लिए कई विकल्प मौजूद हैं. इनमें ये शामिल हैं:
एक्सटेंसिबल मैसेजिंग ऐंड प्रेज़ेंस प्रोटोकॉल (एक्सएमपीपी) एक ऐसा प्रोटोकॉल है जिसे फटाफट मैसेज सेवा के लिए डेवलप किया गया है. इसका इस्तेमाल सिग्नल भेजने के लिए किया जा सकता है. सर्वर को लागू करने के तरीकों में ejabberd और Openfire शामिल हैं. Strophe.js जैसे JavaScript क्लाइंट, दोनों तरफ़ से स्ट्रीमिंग की सुविधा देने के लिए BOSH का इस्तेमाल करते हैं. हालांकि, WebSocket की तुलना में BOSH कम असरदार हो सकता है और इसे स्केल करना मुश्किल हो सकता है.
ओपन सोर्स लाइब्रेरी, जैसे कि ZeroMQ (इसका इस्तेमाल TokBox अपनी Rumour सेवा के लिए करता है) और OpenMQ (NullMQ, WebSocket पर STOMP प्रोटोकॉल का इस्तेमाल करके, वेब प्लैटफ़ॉर्म पर ZeroMQ के कॉन्सेप्ट लागू करता है.)
WebSocket का इस्तेमाल करने वाले व्यावसायिक क्लाउड-मैसेजिंग प्लैटफ़ॉर्म, जैसे कि Pusher और Kaazing. हालांकि, ये प्लैटफ़ॉर्म लॉन्ग पोलिंग का इस्तेमाल भी कर सकते हैं.
कमर्शियल WebRTC प्लैटफ़ॉर्म, जैसे कि vLine
Node पर Socket.io की मदद से सिग्नलिंग सेवा बनाना
यहां एक ऐसे वेब ऐप्लिकेशन का कोड दिया गया है जो Node पर Socket.io की मदद से बनाई गई सिग्नलिंग सेवा का इस्तेमाल करता है. Socket.io के डिज़ाइन की वजह से, मैसेज शेयर करने के लिए सेवा बनाना आसान हो जाता है. साथ ही, Socket.io खास तौर पर WebRTC सिग्नलिंग के लिए सही है, क्योंकि इसमें रूम का कॉन्सेप्ट पहले से मौजूद होता है. इस उदाहरण को प्रोडक्शन के बजाय, कुछ उपयोगकर्ताओं के लिए डिज़ाइन किया गया है.
Socket.io, फ़ॉलबैक के साथ WebSocket का इस्तेमाल करता है: AJAX लॉन्ग पोलिंग, AJAX मल्टीपार्ट स्ट्रीमिंग, Forever Iframe, और JSONP पोलिंग. इसे कई बैकएंड पर पोर्ट किया गया है. हालांकि, इस उदाहरण में इस्तेमाल किए गए Node वर्शन के लिए इसे सबसे ज़्यादा जाना जाता है.
इस उदाहरण में WebRTC का इस्तेमाल नहीं किया गया है. इसे वेब ऐप्लिकेशन में सिग्नलिंग बनाने का तरीका दिखाने के लिए डिज़ाइन किया गया है. कंसोल लॉग देखें और जानें कि क्लाइंट के रूम में शामिल होने और मैसेज शेयर करने पर क्या होता है. इस WebRTC कोडलैब में, इसे WebRTC वीडियो चैट ऐप्लिकेशन में इंटिग्रेट करने के सिलसिलेवार निर्देश दिए गए हैं.
यहां क्लाइंट index.html दिया गया है:
<!DOCTYPE html>
<html>
<head>
<title>WebRTC client</title>
</head>
<body>
<script src='/socket.io/socket.io.js'></script>
<script src='js/main.js'></script>
</body>
</html>
यहां JavaScript फ़ाइल main.js दी गई है, जिसे क्लाइंट में रेफ़रंस के तौर पर इस्तेमाल किया गया है:
const isInitiator;
room = prompt('Enter room name:');
const socket = io.connect();
if (room !== '') {
console.log('Joining room ' + room);
socket.emit('create or join', room);
}
socket.on('full', (room) => {
console.log('Room ' + room + ' is full');
});
socket.on('empty', (room) => {
isInitiator = true;
console.log('Room ' + room + ' is empty');
});
socket.on('join', (room) => {
console.log('Making request to join room ' + room);
console.log('You are the initiator!');
});
socket.on('log', (array) => {
console.log.apply(console, array);
});
यहां सर्वर ऐप्लिकेशन का पूरा कोड दिया गया है:
const static = require('node-static');
const http = require('http');
const file = new(static.Server)();
const app = http.createServer(function (req, res) {
file.serve(req, res);
}).listen(2013);
const io = require('socket.io').listen(app);
io.sockets.on('connection', (socket) => {
// Convenience function to log server messages to the client
function log(){
const array = ['>>> Message from server: '];
for (const i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
socket.on('message', (message) => {
log('Got message:', message);
// For a real app, would be room only (not broadcast)
socket.broadcast.emit('message', message);
});
socket.on('create or join', (room) => {
const numClients = io.sockets.clients(room).length;
log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room ' + room);
if (numClients === 0){
socket.join(room);
socket.emit('created', room);
} else if (numClients === 1) {
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
} else { // max two clients
socket.emit('full', room);
}
socket.emit('emit(): client ' + socket.id +
' joined room ' + room);
socket.broadcast.emit('broadcast(): client ' + socket.id +
' joined room ' + room);
});
});
इस ऐप्लिकेशन को लोकलहोस्ट पर चलाने के लिए, आपके पास Node.js, Socket.IO, और node-static होना चाहिए. Socket.IO और node-static को इंस्टॉल करने के लिए, अपनी ऐप्लिकेशन डायरेक्ट्री में टर्मिनल से npm चलाएं:
npm install socket.io
npm install node-static
सर्वर शुरू करने के लिए, अपनी ऐप्लिकेशन डायरेक्ट्री में टर्मिनल से यह कमांड चलाएं:
node server.js
अपने ब्राउज़र में, localhost:2013 खोलें. किसी भी ब्राउज़र में नया टैब या विंडो खोलें और localhost:2013 को फिर से खोलें. क्या हो रहा है, यह देखने के लिए कंसोल देखें. Chrome और Opera में, Google Chrome डेवलपर टूल की मदद से कंसोल को ऐक्सेस किया जा सकता है. इसके लिए, Ctrl+Shift+J (या Mac पर Command+Option+J) दबाएं.
सिग्नल भेजने के लिए, चाहे कोई भी तरीका चुना जाए, आपके बैकएंड और क्लाइंट ऐप्लिकेशन को इस उदाहरण की तरह ही सेवाएं देनी होंगी.
सिग्नल से जुड़ी समस्याएं
RTCPeerConnectionतब तक कैंडिडेट इकट्ठा करना शुरू नहीं करेगा, जब तकsetLocalDescription()को कॉल नहीं किया जाता. यह जेएसईपी आईईटीएफ़ ड्राफ़्ट में ज़रूरी है.- ट्रिकल आईसीई का फ़ायदा लें. उम्मीदवारों के आते ही
addIceCandidate()को कॉल करें.
पहले से तैयार सिग्नल सर्वर
अगर आपको अपना सर्वर नहीं बनाना है, तो WebRTC सिग्नलिंग के कई सर्वर उपलब्ध हैं. ये पिछले उदाहरण की तरह Socket.IO का इस्तेमाल करते हैं और WebRTC क्लाइंट JavaScript लाइब्रेरी के साथ इंटिग्रेट होते हैं:
- webRTC.io, WebRTC के लिए सबसे पहली ऐब्स्ट्रैक्शन लाइब्रेरी में से एक है.
- Signalmaster एक सिग्नलिंग सर्वर है. इसे SimpleWebRTC JavaScript क्लाइंट लाइब्रेरी के साथ इस्तेमाल करने के लिए बनाया गया है.
अगर आपको कोई कोड नहीं लिखना है, तो vLine, OpenTok, और Asterisk जैसी कंपनियों के कमर्शियल WebRTC प्लैटफ़ॉर्म का इस्तेमाल करें.
आपकी जानकारी के लिए बता दें कि Ericsson ने WebRTC के शुरुआती दिनों में, Apache पर PHP का इस्तेमाल करके एक सिग्नलिंग सर्वर बनाया था. यह अब थोड़ा पुराना हो गया है, लेकिन अगर आपको कुछ ऐसा ही बनाना है, तो कोड को देखना फ़ायदेमंद रहेगा.
सिग्नल की सुरक्षा
WebRTC के सभी कॉम्पोनेंट के लिए, एन्क्रिप्शन ज़रूरी है.
हालांकि, WebRTC के स्टैंडर्ड में सिग्नलिंग के तरीके तय नहीं किए गए हैं. इसलिए, सिग्नलिंग को सुरक्षित बनाने की ज़िम्मेदारी आपकी है. अगर कोई हमलावर सिग्नल को हाइजैक कर लेता है, तो वह सेशन को रोक सकता है, कनेक्शन को रीडायरेक्ट कर सकता है, और कॉन्टेंट को रिकॉर्ड कर सकता है, उसमें बदलाव कर सकता है या उसे इंजेक्ट कर सकता है.
सिग्नलिंग को सुरक्षित रखने के लिए सबसे ज़रूरी है कि सुरक्षित प्रोटोकॉल का इस्तेमाल किया जाए: एचटीटीपीएस और डब्ल्यूएसएस, जैसे कि टीएलएस. इससे यह पक्का होता है कि एन्क्रिप्ट (सुरक्षित) न किए गए मैसेज को कोई इंटरसेप्ट न कर सके. साथ ही, इस बात का ध्यान रखें कि सिग्नल मैसेज को इस तरह ब्रॉडकास्ट न किया जाए कि एक ही सिग्नल सर्वर का इस्तेमाल करने वाले अन्य कॉलर उन्हें ऐक्सेस कर सकें.
एनएटी और फ़ायरवॉल के साथ काम करना
मेटाडेटा सिग्नल के लिए, WebRTC ऐप्लिकेशन किसी इंटरमीडियरी सर्वर का इस्तेमाल करते हैं. हालांकि, सेशन शुरू होने के बाद, असल मीडिया और डेटा स्ट्रीमिंग के लिए, RTCPeerConnection क्लाइंट को सीधे या पीयर-टू-पीयर कनेक्ट करने की कोशिश करता है.
अगर दुनिया आसान होती, तो हर WebRTC एंडपॉइंट का एक यूनीक पता होता. इसे सीधे तौर पर कम्यूनिकेट करने के लिए, अन्य पीयर के साथ शेयर किया जा सकता था.
असल में, ज़्यादातर डिवाइस NAT की एक या उससे ज़्यादा लेयर के पीछे होते हैं. कुछ डिवाइसों में ऐंटीवायरस सॉफ़्टवेयर होता है, जो कुछ पोर्ट और प्रोटोकॉल को ब्लॉक कर देता है. इसके अलावा, कई डिवाइस प्रॉक्सी और कॉर्पोरेट फ़ायरवॉल के पीछे होते हैं. फ़ायरवॉल और एनएटी को एक ही डिवाइस से लागू किया जा सकता है. जैसे, घर का वाई-फ़ाई राऊटर.
WebRTC ऐप्लिकेशन, ICE फ़्रेमवर्क का इस्तेमाल करके, असल दुनिया की नेटवर्किंग की जटिलताओं को दूर कर सकते हैं. इस सुविधा को चालू करने के लिए, आपके ऐप्लिकेशन को RTCPeerConnection को ICE सर्वर के यूआरएल भेजने होंगे.
ICE, पीयर को कनेक्ट करने के लिए सबसे सही पाथ ढूंढने की कोशिश करता है. यह एक साथ सभी संभावनाओं को आज़माता है और सबसे असरदार विकल्प चुनता है. ICE सबसे पहले, किसी डिवाइस के ऑपरेटिंग सिस्टम और नेटवर्क कार्ड से मिले होस्ट पते का इस्तेमाल करके कनेक्शन बनाने की कोशिश करता है. अगर यह तरीका काम नहीं करता (एनएटी के पीछे मौजूद डिवाइसों के लिए ऐसा होगा), तो ICE, STUN सर्वर का इस्तेमाल करके बाहरी पता हासिल करता है. अगर यह तरीका भी काम नहीं करता, तो ट्रैफ़िक को TURN रिले सर्वर के ज़रिए रूट किया जाता है.
दूसरे शब्दों में, STUN सर्वर का इस्तेमाल बाहरी नेटवर्क पता पाने के लिए किया जाता है. वहीं, TURN सर्वर का इस्तेमाल ट्रैफ़िक को रिले करने के लिए किया जाता है. ऐसा तब किया जाता है, जब डायरेक्ट (पीयर-टू-पीयर) कनेक्शन काम न करे.
हर TURN सर्वर, STUN के साथ काम करता है. TURN सर्वर एक STUN सर्वर होता है, जिसमें पहले से मौजूद रिलेइंग की अतिरिक्त सुविधा होती है. ICE, एनएटी सेटअप की जटिलताओं को भी मैनेज करता है. असल में, एनएटी होल-पंचिंग के लिए, सिर्फ़ सार्वजनिक आईपी:पोर्ट पते से ज़्यादा की ज़रूरत पड़ सकती है.
STUN और TURN सर्वर के यूआरएल, WebRTC ऐप्लिकेशन से (ज़रूरी नहीं) iceServers कॉन्फ़िगरेशन ऑब्जेक्ट में तय किए जाते हैं. यह RTCPeerConnection कंस्ट्रक्टर का पहला आर्ग्युमेंट होता है. appr.tc के लिए, वह वैल्यू कुछ ऐसी दिखती है:
{
'iceServers': [
{
'urls': 'stun:stun.l.google.com:19302'
},
{
'urls': 'turn:192.158.29.39:3478?transport=udp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
},
{
'urls': 'turn:192.158.29.39:3478?transport=tcp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
}
]
}
RTCPeerConnection को यह जानकारी मिलने के बाद, आईसीई का जादू अपने-आप शुरू हो जाता है. RTCPeerConnection, ICE फ़्रेमवर्क का इस्तेमाल करके, पीयर के बीच सबसे अच्छा पाथ तय करता है. इसके लिए, वह ज़रूरत के हिसाब से STUN और TURN सर्वर का इस्तेमाल करता है.
एसटीयूएन
NAT किसी डिवाइस को एक आईपी पता उपलब्ध कराते हैं, ताकि उसे निजी लोकल नेटवर्क में इस्तेमाल किया जा सके. हालांकि, इस पते का इस्तेमाल बाहरी तौर पर नहीं किया जा सकता. सार्वजनिक पते के बिना, WebRTC पीयर के लिए कम्यूनिकेट करना मुमकिन नहीं है. इस समस्या को हल करने के लिए, WebRTC STUN का इस्तेमाल करता है.
STUN सर्वर, सार्वजनिक इंटरनेट पर मौजूद होते हैं और इनका एक ही काम होता है: NAT के पीछे चल रहे किसी ऐप्लिकेशन से आने वाले अनुरोध के आईपी:पोर्ट पते की जांच करना और उस पते को जवाब के तौर पर वापस भेजना. दूसरे शब्दों में, ऐप्लिकेशन सार्वजनिक तौर पर अपने आईपी:पोर्ट का पता लगाने के लिए, STUN सर्वर का इस्तेमाल करता है. इस प्रोसेस की मदद से, WebRTC पीयर को सार्वजनिक तौर पर ऐक्सेस किया जा सकने वाला पता मिलता है. इसके बाद, वह सिग्नलिंग मैकेनिज़्म के ज़रिए, इस पते को दूसरे पीयर को भेजता है, ताकि डायरेक्ट लिंक सेट अप किया जा सके.
STUN सर्वर को ज़्यादा काम नहीं करना पड़ता या ज़्यादा जानकारी याद नहीं रखनी पड़ती. इसलिए, कम क्षमता वाले STUN सर्वर भी बड़ी संख्या में अनुरोधों को हैंडल कर सकते हैं.
ज़्यादातर WebRTC कॉल, STUN का इस्तेमाल करके कनेक्ट हो जाते हैं. हालांकि, फ़ायरवॉल और जटिल एनएटी कॉन्फ़िगरेशन के पीछे मौजूद पीयर के बीच होने वाले कॉल के लिए, यह संख्या कम हो सकती है.
TURN
RTCPeerConnection, यूडीपी पर पीयर के बीच सीधे कम्यूनिकेशन सेट अप करने की कोशिश करता है.
अगर ऐसा नहीं हो पाता है, तो RTCPeerConnection टीसीपी का इस्तेमाल करता है. अगर यह तरीका काम नहीं करता है, तो TURN सर्वर का इस्तेमाल दूसरे विकल्प के तौर पर किया जा सकता है. इससे एंडपॉइंट के बीच डेटा रिले किया जा सकता है.
एक बार फिर बता दें कि TURN का इस्तेमाल, पीयर के बीच ऑडियो, वीडियो, और डेटा स्ट्रीमिंग को रिले करने के लिए किया जाता है, न कि डेटा को सिग्नल करने के लिए!
TURN सर्वर के पते सार्वजनिक होते हैं. इसलिए, पीयर उनसे संपर्क कर सकते हैं. भले ही, पीयर फ़ायरवॉल या प्रॉक्सी के पीछे हों. टर्न सर्वर का एक ही काम होता है: स्ट्रीम को रिले करना. STUN सर्वर के उलट, ये बहुत ज़्यादा बैंडविड्थ का इस्तेमाल करते हैं.
इस डायग्राम में, TURN के काम करने का तरीका दिखाया गया है. प्योर STUN सफल नहीं हुआ, इसलिए हर पीयर TURN सर्वर का इस्तेमाल करता है.
STUN और TURN सर्वर डिप्लॉय करना
टेस्टिंग के लिए, Google एक सार्वजनिक STUN सर्वर, stun.l.google.com:19302 चलाता है. इसका इस्तेमाल appr.tc करता है. STUN/TURN सेवा के प्रोडक्शन के लिए, rfc5766-turn-server का इस्तेमाल करें. STUN और TURN सर्वर के लिए सोर्स कोड, GitHub पर उपलब्ध है. यहां आपको सर्वर इंस्टॉल करने के बारे में जानकारी देने वाले कई सोर्स के लिंक भी मिल सकते हैं. Amazon Web Services के लिए वीएम इमेज भी उपलब्ध है.
एक अन्य TURN सर्वर, restund है. यह सोर्स कोड के तौर पर और AWS के लिए भी उपलब्ध है. Compute पर restund सेट अप किया जा सकता है :
- ज़रूरत के हिसाब से, tcp=443, udp/tcp=3478 के लिए फ़ायरवॉल खोलें.
- चार इंस्टेंस बनाएं. हर सार्वजनिक आईपी के लिए एक इंस्टेंस बनाएं. इसके लिए, स्टैंडर्ड Ubuntu 12.06 इमेज का इस्तेमाल करें.
- लोकल फ़ायरवॉल कॉन्फ़िगरेशन सेट अप करें (सभी को अनुमति दें).
- टूल इंस्टॉल करें:
shell sudo apt-get install make sudo apt-get install gcc - creytiv.com/re.html से libre इंस्टॉल करें.
- creytiv.com/restund.html से restund फ़ेच करें और अनपैक करें.
wgethancke.name/restund-auth.patch डाउनलोड करें औरpatch -p1 < restund-auth.patchका इस्तेमाल करके लागू करें.- libre और restund के लिए
make,sudo make installचलाएं. restund.confको अपनी ज़रूरत के हिसाब से अडैप्ट करें (आईपी पते बदलें और पक्का करें कि इसमें वही शेयर किया गया सीक्रेट शामिल हो) और/etcमें कॉपी करें.restund/etc/restundको/etc/init.d/में कॉपी करें.- restund को कॉन्फ़िगर करें:
LD_LIBRARY_PATHसेट करें.restund.confको/etc/restund.confमें कॉपी करें.restund.confको दाईं ओर 10 पर सेट करें. आईपी पता.
- restund चलाएं
- रिमोट मशीन से stund क्लाइंट का इस्तेमाल करके टेस्ट करें:
./client IP:port
मल्टी-पार्टी WebRTC
आपको TURN सेवाओं को ऐक्सेस करने के लिए REST API के लिए, जस्टिन उबर्टी के सुझाए गए आईईटीएफ़ स्टैंडर्ड को भी देखना चाहिए.
मीडिया स्ट्रीमिंग के कई इस्तेमाल हैं. जैसे, वन-टू-वन कॉल के अलावा, कई अन्य कामों के लिए भी इसका इस्तेमाल किया जा सकता है. उदाहरण के लिए, साथ काम करने वाले लोगों के ग्रुप के बीच वीडियो कॉन्फ़्रेंसिंग या कोई सार्वजनिक इवेंट, जिसमें एक स्पीकर और सैकड़ों या लाखों दर्शक हों.
WebRTC ऐप्लिकेशन, कई RTCPeerConnections का इस्तेमाल कर सकता है, ताकि हर एंडपॉइंट, मेश कॉन्फ़िगरेशन में मौजूद हर दूसरे एंडपॉइंट से कनेक्ट हो सके. talky.io जैसे ऐप्लिकेशन, इस तरीके का इस्तेमाल करते हैं. यह तरीका, कुछ ही लोगों के लिए बहुत अच्छी तरह से काम करता है. इससे ज़्यादा होने पर, प्रोसेसिंग और बैंडविड्थ की खपत बहुत ज़्यादा हो जाती है. खास तौर पर, मोबाइल क्लाइंट के लिए.
इसके अलावा, WebRTC ऐप्लिकेशन, स्टार कॉन्फ़िगरेशन में अन्य सभी को स्ट्रीम डिस्ट्रिब्यूट करने के लिए, एक एंडपॉइंट चुन सकता है. सर्वर पर WebRTC एंडपॉइंट को चलाना और अपना रीडिस्ट्रिब्यूशन मैकेनिज़्म बनाना भी मुमकिन है. webrtc.org ने एक सैंपल क्लाइंट ऐप्लिकेशन उपलब्ध कराया है.
एक RTCPeerConnection से मिले MediaStream को दूसरे के लिए इनपुट के तौर पर इस्तेमाल किया जा सकता है. इससे ज़्यादा सुविधाजनक आर्किटेक्चर चालू किए जा सकते हैं, क्योंकि इससे वेब ऐप्लिकेशन को कॉल-रूटिंग मैनेज करने की सुविधा मिलती है. इसके लिए, यह चुना जाता है कि किस दूसरे पीयर से कनेक्ट करना है. इसे काम करते हुए देखने के लिए, WebRTC के सैंपल पीयर कनेक्शन रिले और WebRTC के सैंपल कई पीयर कनेक्शन देखें.
मल्टीपॉइंट कंट्रोल यूनिट
ज़्यादा एंडपॉइंट के लिए, मल्टीपॉइंट कंट्रोल यूनिट (एमसीयू) का इस्तेमाल करना बेहतर विकल्प है. यह एक ऐसा सर्वर है जो मीटिंग में हिस्सा लेने वाले कई लोगों के बीच मीडिया को डिस्ट्रिब्यूट करने के लिए, एक ब्रिज के तौर पर काम करता है. एमसीयू, वीडियो कॉन्फ़्रेंस में अलग-अलग रिज़ॉल्यूशन, कोडेक, और फ़्रेम रेट को मैनेज कर सकते हैं. साथ ही, ट्रांसकोडिंग को मैनेज कर सकते हैं, चुनिंदा स्ट्रीम को फ़ॉरवर्ड कर सकते हैं, और ऑडियो और वीडियो को मिक्स या रिकॉर्ड कर सकते हैं. मल्टीपार्टी कॉल के लिए, कई समस्याओं पर ध्यान देना ज़रूरी है. खास तौर पर, एक से ज़्यादा वीडियो इनपुट दिखाने और कई सोर्स से ऑडियो को मिक्स करने के तरीके पर. vLine जैसे क्लाउड प्लैटफ़ॉर्म भी ट्रैफ़िक रूटिंग को ऑप्टिमाइज़ करने की कोशिश करते हैं.
एमसीयू हार्डवेयर का पूरा पैकेज खरीदा जा सकता है या खुद का पैकेज बनाया जा सकता है.
कई ओपन सोर्स एमसीयू सॉफ़्टवेयर विकल्प उपलब्ध हैं. उदाहरण के लिए, Licode (पहले Lynckia के नाम से जाना जाता था) WebRTC के लिए एक ओपन सोर्स एमसीयू बनाता है. OpenTok के पास Mantis है.
ब्राउज़र के अलावा: वीओआईपी, टेलीफ़ोन, और मैसेजिंग
WebRTC के स्टैंडर्ड नेचर की वजह से, ब्राउज़र में चल रहे WebRTC ऐप्लिकेशन और किसी दूसरे कम्यूनिकेशन प्लैटफ़ॉर्म पर चल रहे डिवाइस या प्लैटफ़ॉर्म के बीच कम्यूनिकेशन किया जा सकता है. जैसे, टेलीफ़ोन या वीडियो-कॉन्फ़्रेंसिंग सिस्टम.
SIP एक सिग्नलिंग प्रोटोकॉल है. इसका इस्तेमाल वीओआईपी और वीडियो कॉन्फ़्रेंसिंग सिस्टम करते हैं. WebRTC वेब ऐप्लिकेशन और एसआईपी क्लाइंट के बीच कम्यूनिकेशन चालू करने के लिए, WebRTC को सिग्नल भेजने के लिए प्रॉक्सी सर्वर की ज़रूरत होती है. एसआईपी क्लाइंट का उदाहरण वीडियो-कॉन्फ़्रेंसिंग सिस्टम है. सिग्नल, गेटवे से होकर गुज़रना चाहिए. हालांकि, कनेक्शन सेट अप होने के बाद, एसआरटीपी ट्रैफ़िक (वीडियो और ऑडियो) पीयर-टू-पीयर हो सकता है.
पब्लिक स्विच्ड टेलीफ़ोन नेटवर्क (पीएसटीएन), सभी "पुराने" एनालॉग टेलीफ़ोन का सर्किट-स्विच्ड नेटवर्क है. WebRTC वेब ऐप्लिकेशन और टेलीफ़ोन के बीच कॉल के लिए, ट्रैफ़िक को पीएसटीएन गेटवे से गुज़रना होगा. इसी तरह, WebRTC वेब ऐप्लिकेशन को Jingle एंडपॉइंट, जैसे कि आईएम क्लाइंट के साथ कम्यूनिकेट करने के लिए, एक इंटरमीडियरी XMPP सर्वर की ज़रूरत होती है. Google ने Jingle को XMPP के एक्सटेंशन के तौर पर डेवलप किया था, ताकि मैसेज सेवा में ऑडियो और वीडियो की सुविधा जोड़ी जा सके. WebRTC को लागू करने के मौजूदा तरीके, C++ libjingle लाइब्रेरी पर आधारित हैं. यह Jingle को लागू करने का एक तरीका है, जिसे शुरुआत में Talk के लिए डेवलप किया गया था.
कई ऐप्लिकेशन, लाइब्रेरी, और प्लैटफ़ॉर्म, WebRTC की क्षमता का इस्तेमाल करके बाहरी दुनिया से संपर्क करते हैं. उदाहरण के लिए:
- jsSIP: JavaScript SIP लाइब्रेरी
- Phono: प्लगिन के तौर पर बनाया गया ओपन सोर्स JavaScript फ़ोन एपीआई
- Twilio: वॉइस और मैसेज सेवा
ज़्यादा जानें
- WebRTC API से जुड़ा दस्तावेज़ पढ़ें.
- WebRTC कोडलैब में, Node पर चल रही Socket.io सिग्नल सेवा का इस्तेमाल करके, वीडियो और टेक्स्ट चैट ऐप्लिकेशन बनाने के सिलसिलेवार निर्देश दिए गए हैं.
- क्रिस विल्सन का SFHTML5 प्रज़ेंटेशन: WebRTC ऐप्लिकेशन के बारे में जानकारी
WebRTC: APIs and RTCWEB Protocols of the HTML5 Real-Time Web नाम की 350 पेज की किताब में, डेटा और सिग्नलिंग पाथवे के बारे में काफ़ी जानकारी दी गई है. इसमें नेटवर्क टोपोलॉजी के कई डायग्राम भी शामिल हैं.