पीयर कनेक्शन, WebRTC की विशेषताओं का हिस्सा है. यह पीयर-टू-पीयर प्रोटोकॉल का इस्तेमाल करके अलग-अलग कंप्यूटर पर
दो ऐप्लिकेशन कनेक्ट करता है. मिलते-जुलते ऐप्लिकेशन के बीच कम्यूनिकेशन, वीडियो (ऑडियो) या आर्बिट्ररी बाइनरी डेटा (क्लाइंट RTCDataChannel
के लिए काम करने वाला क्लाइंट) हो सकता है. यह पता लगाने के लिए कि मिलते-जुलते दो ऐप्लिकेशन कैसे कनेक्ट कर सकते हैं, दोनों क्लाइंट को ICE सर्वर कॉन्फ़िगरेशन देना होगा. यह एक STUN या टर्न-सर्वर होता है और इनकी भूमिका हर क्लाइंट को ICE की सुविधा देने की होती है, जिसे बाद में दूर रहकर काम करने वाले लोगों को ट्रांसफ़र किया जाता है. आईसीई उम्मीदवारों के इस ट्रांसफ़र को आम तौर पर सिग्नलिंग कहा जाता है.
सिग्नलिंग
WebRTC की जानकारी में ICE (इंटरनेट कनेक्टिविटी इंस्टॉलेशन) सर्वर से संपर्क करने के लिए एपीआई शामिल हैं. हालांकि, इसके सिग्नल का कॉम्पोनेंट भी शामिल नहीं है. दो मिलते-जुलते ऐप्लिकेशन से शेयर करने के लिए, सिग्नल को जोड़ना ज़रूरी है. आम तौर पर, इसे नियमित एचटीटीपी आधारित वेब एपीआई (जैसे कि REST सेवा या अन्य आरपीसी तकनीक) से हल किया जाता है. यहां वेब ऐप्लिकेशन, मिलते-जुलते ऐप्लिकेशन का कनेक्शन शुरू होने से पहले ज़रूरी जानकारी रिले कर सकते हैं.
आगे दिए गए कोड स्निपेट से पता चलता है कि इस काल्पनिक सिग्नलिंग सेवा का इस्तेमाल करके मैसेज कैसे एसिंक्रोनस तरीके से भेजे और पाए जा सकते हैं. जहां ज़रूरी होगा, वहां इस गाइड के बाकी उदाहरणों में इसका इस्तेमाल किया जाएगा.
// Set up an asynchronous communication channel that will be
// used during the peer connection setup
const signalingChannel = new SignalingChannel(remoteClientId);
signalingChannel.addEventListener('message', message => {
// New message from remote client received
});
// Send an asynchronous message to the remote client
signalingChannel.send('Hello!');
सिग्नलिंग कई अलग-अलग तरीकों से लागू की जा सकती है. साथ ही, WebRTC की खास बातों में #39 शामिल नहीं है.
मिलते-जुलते ऐप्लिकेशन के कनेक्शन शुरू करना
मिलते-जुलते ऐप्लिकेशन के हर कनेक्शन को RTCPeerConnection
ऑब्जेक्ट मैनेज करता है. इस क्लास के लिए कंस्ट्रक्टर
अपने पैरामीटर के रूप में एक RTCConfiguration
ऑब्जेक्ट लेता है. यह ऑब्जेक्ट बताता है कि पीयर कनेक्शन को कैसे सेट अप किया गया है और उसमें इस्तेमाल किए जाने वाले ICE सर्वर के बारे में जानकारी होनी चाहिए.
RTCPeerConnection
बनाने के बाद, हमें एसडीपी ऑफ़र या जवाब बनाना होगा. यह इस बात पर निर्भर करता है कि हम कॉल करने वाले मिलते-जुलते ऐप्लिकेशन या कॉल करने वाले मिलते हैं या नहीं. जब एसडीपी ऑफ़र या जवाब तैयार हो जाता है, तो इसे एक अलग चैनल के ज़रिए रिमोट पीयर को भेजा जाना चाहिए. एसडीपी ऑब्जेक्ट को दूर से मिलते-जुलते ऐप्लिकेशन पर पास करना, सिग्नलिंग कहते हैं और वे WebRTC की खास बातों में शामिल नहीं हैं.
मिलते-जुलते ऐप्लिकेशन से कॉल करने के लिए, मिलते-जुलते ऐप्लिकेशन का सेट अप शुरू करने के लिए, हम
RTCPeerConnection
ऑब्जेक्ट बनाते हैं और फिर
RTCSessionDescription
ऑब्जेक्ट बनाने के लिए createOffer()
को कॉल करते हैं. सेशन के इस ब्यौरे को setLocalDescription()
का इस्तेमाल करके, स्थानीय जानकारी के तौर पर सेट किया जाता है. इसके बाद, इसे सिग्नल देने वाले हमारे चैनल पर भेजा जाता है. हम अपने सिग्नल देने वाले चैनल के लिए, एक लिसनर भी सेट अप करते हैं. ऐसा हम तब करते हैं, जब हमारे सेशन के ब्यौरे का जवाब हमारी तरफ़ से मिलता है.
async function makeCall() {
const configuration = {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]}
const peerConnection = new RTCPeerConnection(configuration);
signalingChannel.addEventListener('message', async message => {
if (message.answer) {
const remoteDesc = new RTCSessionDescription(message.answer);
await peerConnection.setRemoteDescription(remoteDesc);
}
});
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
signalingChannel.send({'offer': offer});
}
पाने का ऑफ़र मिलने तक, हम RTCPeerConnection
इंस्टेंस बनाने से पहले, आने वाले ऑफ़र का इंतज़ार करते हैं. ऐसा करने के बाद, हम
setRemoteDescription()
का इस्तेमाल करके, ऑफ़र पा सकते हैं. फिर, हम मिले ऑफ़र का जवाब देने के लिए createAnswer()
पर कॉल करते हैं. इस जवाब को setLocalDescription()
का इस्तेमाल करके, स्थानीय जानकारी के तौर पर सेट किया जाता है. इसके बाद, इसे हमारे सिग्नल देने वाले सर्वर पर कॉलिंग साइड पर भेजा जाता है.
const peerConnection = new RTCPeerConnection(configuration);
signalingChannel.addEventListener('message', async message => {
if (message.offer) {
peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer));
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
signalingChannel.send({'answer': answer});
}
});
जब दो मिलते-जुलते ऐप्लिकेशन ने लोकल और रिमोट सेशन के ब्यौरे को सेट किया हो, तब उन्हें रिमोट पीयर की क्षमताओं के बारे में पता चल जाता है. इसका मतलब यह नहीं है कि मिलते-जुलते ऐप्लिकेशन के साथ कनेक्शन तैयार है. इसे काम करने के लिए, हमें हर मिलते-जुलते ऐप्लिकेशन से ICE कैंडिडेट इकट्ठा करने और सिग्नलिंग चैनल पर कुछ और ट्रांसफ़र करने की ज़रूरत होगी.
ICE के उम्मीदवार
दो मिलते-जुलते ऐप्लिकेशन, WebRTC का इस्तेमाल करके एक-दूसरे से संपर्क कर सकें, इसके लिए उन्हें कनेक्टिविटी की जानकारी का लेन-देन करना होगा. नेटवर्क की स्थिति कई वजहों से अलग-अलग हो सकती है. इसलिए, किसी बाहरी सेवा का इस्तेमाल करके, अक्सर मिलते-जुलते ऐप्लिकेशन से जुड़ने के लिए संभावित उम्मीदवारों का पता लगाया जाता है. इस सेवा को ICE कहा जाता है और यह STUN या टर्न सर्वर का इस्तेमाल करती है. STUN का मतलब है NAT के लिए सेशन ट्रैवर्सल यूटिलिटी. इसका इस्तेमाल आम तौर पर WebRTC के ज़्यादातर ऐप्लिकेशन में किया जाता है.
टर्न (Relay का इस्तेमाल करके रिले NAT) एक ज़्यादा बेहतर समाधान है, जिसमें STUN प्रोटोकॉल शामिल हैं. साथ ही, इसकी मदद से ज़्यादातर पेशेवर WebRTC आधारित सेवाएं, टर्न सर्वर का इस्तेमाल करके मिलते-जुलते ऐप्लिकेशन को जोड़ने का काम करती हैं. WebRTC API सीधे तौर पर STUN
और टर्न दोनों का इस्तेमाल करता है.
साथ ही, यह सुविधा ज़्यादा लंबे समय तक इंटरनेट कनेक्टिविटी बनाए रखने में भी काम करती है. WebRTC कनेक्शन बनाते समय, हम आम तौर पर
RTCPeerConnection
ऑब्जेक्ट के कॉन्फ़िगरेशन में एक या एक से ज़्यादा ICE सर्वर देते हैं.
ट्रिकल आईसीई
एक बार RTCPeerConnection
ऑब्जेक्ट बन जाने पर, बुनियादी फ़्रेमवर्क, कनेक्टिविटी वाले संगठन (ICE की उम्मीदवारों) के लिए उम्मीदवारों को इकट्ठा करने के लिए, दिए गए ICE सर्वर का इस्तेमाल करता है. RTCPeerConnection
पर icegatheringstatechange
इवेंट से यह पता चलता है कि
ICE मीटिंग किस स्थिति में है (new
, gathering
या complete
).
हालांकि, मिलते-जुलते ऐप्लिकेशन के लिए ICE इकट्ठा होने के बाद तक इंतज़ार करना संभव है, लेकिन आम तौर पर यह &&tt>कचरे से जुड़ी आइस&कोच की तकनीक का इस्तेमाल करने के साथ-साथ, हर ICE उम्मीदवार को दूर मौजूद मिलते-जुलते ऐप्लिकेशन से गुज़रता है. इससे मिलते-जुलते ऐप्लिकेशन के सेट अप में लगने वाला समय काफ़ी कम हो जाएगा. साथ ही, वीडियो कॉल शुरू करने में कम समय लगेगा.
ICE के सदस्यों को इकट्ठा करने के लिए, icecandidate
इवेंट के लिए लिसनर जोड़ें.
उस लिसनर पर जारी होने वाली RTCPeerConnectionIceEvent
में एक ऐसी candidate
प्रॉपर्टी शामिल होगी जो किसी ऐसे नए उम्मीदवार के बारे में बताती है जिसे रिमोट पीयर को (सिग्लिंग देखें) पर भेजा जाना चाहिए.
// Listen for local ICE candidates on the local RTCPeerConnection
peerConnection.addEventListener('icecandidate', event => {
if (event.candidate) {
signalingChannel.send({'new-ice-candidate': event.candidate});
}
});
// Listen for remote ICE candidates and add them to the local RTCPeerConnection
signalingChannel.addEventListener('message', async message => {
if (message.iceCandidate) {
try {
await peerConnection.addIceCandidate(message.iceCandidate);
} catch (e) {
console.error('Error adding received ice candidate', e);
}
}
});
कनेक्शन स्थापित
आईसीई के उम्मीदवारों के शामिल होने के बाद, हमें उम्मीद है कि मिलते-जुलते ऐप्लिकेशन के कनेक्शन की स्थिति, बदलकर 'कनेक्टेड स्टेट' कर दी जाएगी. इसका पता लगाने के लिए, हम अपने RTCPeerConnection
में एक दर्शक शामिल करते हैं, जहां हम connectionstatechange
इवेंट सुनते हैं.
// Listen for connectionstatechange on the local RTCPeerConnection
peerConnection.addEventListener('connectionstatechange', event => {
if (peerConnection.connectionState === 'connected') {
// Peers connected!
}
});