WebRTC অ্যাপের ব্যাকএন্ড পরিষেবা তৈরি করুন

প্রকাশিত: ০৪ নভেম্বর, ২০১৩

WebRTC পিয়ার-টু-পিয়ার যোগাযোগ সক্ষম করে। এর জন্য সার্ভারের প্রয়োজন হয়, যাতে ক্লায়েন্টরা মেটাডেটা বিনিময় করতে পারে এবং সিগন্যালিং নামক একটি প্রক্রিয়ার মাধ্যমে যোগাযোগ সমন্বয় করতে পারে। সার্ভারগুলো ক্লায়েন্টদের নেটওয়ার্ক অ্যাড্রেস ট্রান্সলেটর (NAT) এবং ফায়ারওয়ালের মতো প্রতিবন্ধকতা মোকাবিলা করতেও সাহায্য করে।

এখানে আপনি শিখবেন কীভাবে একটি সিগন্যালিং পরিষেবা তৈরি করতে হয় এবং STUN ও TURN সার্ভার ব্যবহার করে বাস্তব সংযোগের জটিলতাগুলো সামাল দিতে হয়। এছাড়াও আপনি বুঝতে পারবেন, কীভাবে WebRTC অ্যাপগুলো একাধিক পক্ষের কল পরিচালনা করতে পারে এবং VoIP ও PSTN (যা টেলিফোন নামেও পরিচিত)-এর মতো পরিষেবাগুলোর সাথে যোগাযোগ স্থাপন করতে পারে।

সংকেত দেওয়া বলতে কী বোঝায়?

সিগন্যালিং হলো যোগাযোগ সমন্বয় করার প্রক্রিয়া। একটি WebRTC অ্যাপকে কল সেট আপ করার জন্য, এর ক্লায়েন্টদের নিম্নলিখিত তথ্য আদান-প্রদান করতে হয়:

  • যোগাযোগ শুরু বা বন্ধ করতে সেশন-নিয়ন্ত্রণ বার্তা ব্যবহার করা হয়।
  • ত্রুটির বার্তা
  • মিডিয়া মেটাডেটা, যেমন কোডেক, কোডেক সেটিংস, ব্যান্ডউইথ এবং মিডিয়ার প্রকারভেদ
  • নিরাপদ সংযোগ স্থাপনের জন্য ব্যবহৃত মূল ডেটা
  • নেটওয়ার্ক ডেটা, যেমন বহির্বিশ্বের কাছে দৃশ্যমান একটি হোস্টের আইপি অ্যাড্রেস এবং পোর্ট।

এই সিগন্যালিং প্রক্রিয়ার জন্য ক্লায়েন্টদের মধ্যে বার্তা আদান-প্রদানের একটি মাধ্যম প্রয়োজন। WebRTC API-গুলোতে এই ব্যবস্থাটি বাস্তবায়ন করা নেই। পরিবর্তে, আপনাকে এটি নিজে তৈরি করতে হবে।

WebRTC দ্বারা সিগন্যালিং কেন সংজ্ঞায়িত করা হয় না?

পুনরাবৃত্তি এড়াতে এবং প্রতিষ্ঠিত প্রযুক্তিগুলির সাথে সামঞ্জস্যতা সর্বাধিক করার জন্য, WebRTC স্ট্যান্ডার্ডে সিগন্যালিং পদ্ধতি এবং প্রোটোকল নির্দিষ্ট করা নেই। এই পদ্ধতিটি জাভাস্ক্রিপ্ট সেশন এস্টাবলিশমেন্ট প্রোটোকল (JSEP) দ্বারা বর্ণিত হয়েছে:

JSEP-এর আর্কিটেকচার ব্রাউজারকে স্টেট সংরক্ষণ করা থেকে বিরত রাখে, অর্থাৎ এটিকে সিগন্যালিং স্টেট মেশিন হিসেবে কাজ করতে হয় না। এটি একটি সমস্যা হতে পারত, যেমন, প্রতিবার পেজ রিলোড করার সময় সিগন্যালিং ডেটা হারিয়ে গেলে। এর পরিবর্তে, সিগন্যালিং স্টেট একটি সার্ভারে সংরক্ষণ করা যেতে পারে।

জেএসইপি স্থাপত্য ডায়াগ্রাম

JSEP-এর জন্য পিয়ারদের মধ্যে অফার এবং অ্যানসার , অর্থাৎ মিডিয়া মেটাডেটা, বিনিময় করা প্রয়োজন। অফার এবং অ্যানসার সেশন ডেসক্রিপশন প্রোটোকল (SDP) ফরম্যাটে আদান-প্রদান করা হয়, যা দেখতে এইরকম:

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
...

জানতে চান এই সব এসডিপি (SDP) পরিভাষার আসল অর্থ কী? তাহলে ইন্টারনেট ইঞ্জিনিয়ারিং টাস্ক ফোর্স (IETF)-এর উদাহরণগুলো দেখুন।

মনে রাখবেন যে WebRTC এমনভাবে ডিজাইন করা হয়েছে যাতে অফার বা অ্যানসারকে লোকাল বা রিমোট ডেসক্রিপশন হিসেবে সেট করার আগে SDP টেক্সটের মানগুলো সম্পাদনা করে পরিবর্তন করা যায়। উদাহরণস্বরূপ, appr.tc- তে থাকা preferAudioCodec() ফাংশনটি ডিফল্ট কোডেক এবং বিটরেট সেট করতে ব্যবহার করা যেতে পারে। জাভাস্ক্রিপ্ট দিয়ে SDP নিয়ে কাজ করা কিছুটা কষ্টসাধ্য এবং WebRTC-এর ভবিষ্যৎ সংস্করণগুলোতে এর পরিবর্তে JSON ব্যবহার করা উচিত কিনা তা নিয়ে আলোচনা চলছে, কিন্তু SDP ব্যবহার চালিয়ে যাওয়ার কিছু সুবিধাও রয়েছে।

RTCPeerConnection API এবং সিগন্যালিং: অফার, উত্তর এবং ক্যান্ডিডেট

RTCPeerConnection হলো সেই এপিআই যা WebRTC অ্যাপগুলো পিয়ারদের মধ্যে সংযোগ স্থাপন করতে এবং অডিও ও ভিডিও আদান-প্রদান করতে ব্যবহার করে।

এই প্রক্রিয়াটি শুরু করার জন্য, RTCPeerConnection দুটি কাজ রয়েছে:

  • স্থানীয় মিডিয়ার অবস্থা, যেমন রেজোলিউশন এবং কোডেক সক্ষমতা যাচাই করুন। এই মেটাডেটা অফার-অ্যান্ড-অ্যানসার মেকানিজমের জন্য ব্যবহৃত হয়।
  • অ্যাপটির হোস্টের জন্য সম্ভাব্য নেটওয়ার্ক অ্যাড্রেসগুলো সংগ্রহ করুন, যেগুলো ক্যান্ডিডেট নামে পরিচিত।

এই স্থানীয় তথ্য একবার নিশ্চিত হয়ে গেলে, তা একটি সংকেত আদান-প্রদান প্রক্রিয়ার মাধ্যমে দূরবর্তী পিয়ারের সাথে বিনিময় করতে হবে।

ধরুন অ্যালিস ইভকে ফোন করার চেষ্টা করছে । এর সম্পূর্ণ উত্তর দেওয়ার প্রক্রিয়াটি তার সমস্ত বীভৎস বিবরণসহ নিচে দেওয়া হলো:

  1. অ্যালিস একটি RTCPeerConnection অবজেক্ট তৈরি করে।
  2. অ্যালিস RTCPeerConnection createOffer() মেথড ব্যবহার করে একটি অফার (একটি SDP সেশন বর্ণনা) তৈরি করে।
  3. অ্যালিস তার অফারটি দিয়ে setLocalDescription() কল করে।
  4. অ্যালিস প্রস্তাবটিকে স্ট্রিং-এ রূপান্তর করে এবং একটি সংকেত প্রদানকারী পদ্ধতি ব্যবহার করে তা ইভের কাছে পাঠায়।
  5. ইভ অ্যালিসের অফারটি দিয়ে setRemoteDescription() কল করে, যাতে তার RTCPeerConnection অ্যালিসের সেটআপ সম্পর্কে জানতে পারে।
  6. ইভ createAnswer() কল করে এবং এর সফলতার কলব্যাকে একটি স্থানীয় সেশন বিবরণ—অর্থাৎ ইভের উত্তরটি—পাঠানো হয়।
  7. ইভ setLocalDescription() কল করে তার উত্তরকে স্থানীয় বিবরণ হিসেবে সেট করে।
  8. এরপর ইভ সংকেত পাঠানোর পদ্ধতিটি ব্যবহার করে তার স্ট্রিং-এ রূপান্তরিত উত্তরটি অ্যালিসের কাছে পাঠায়।
  9. অ্যালিস setRemoteDescription() ব্যবহার করে ইভের উত্তরটিকে রিমোট সেশন বিবরণ হিসেবে সেট করে।

অ্যালিস এবং ইভেরও নেটওয়ার্ক তথ্য আদান-প্রদান করার প্রয়োজন রয়েছে। "প্রার্থী খোঁজা" অভিব্যক্তিটি ICE ফ্রেমওয়ার্ক ব্যবহার করে নেটওয়ার্ক ইন্টারফেস এবং পোর্ট খুঁজে বের করার প্রক্রিয়াকে বোঝায়।

  1. অ্যালিস একটি onicecandidate হ্যান্ডলার সহ একটি RTCPeerConnection অবজেক্ট তৈরি করে।
  2. যখন নেটওয়ার্ক ক্যান্ডিডেট উপলব্ধ হয়, তখন হ্যান্ডলারটিকে কল করা হয়।
  3. হ্যান্ডলারে, অ্যালিস তাদের সিগন্যালিং চ্যানেলের মাধ্যমে ইভের কাছে স্ট্রিং-এ রূপান্তরিত সম্ভাব্য ডেটা পাঠায়।
  4. যখন ইভ অ্যালিসের কাছ থেকে একটি ক্যান্ডিডেট মেসেজ পায়, তখন সে ক্যান্ডিডেটটিকে রিমোট পিয়ার ডেসক্রিপশনে যুক্ত করার জন্য addIceCandidate() কল করে।

JSEP, ICE ক্যান্ডিডেট ট্রিকলিং সমর্থন করে, যা কলারকে প্রাথমিক অফারের পর পর্যায়ক্রমে ক্যালিকে ক্যান্ডিডেট সরবরাহ করার সুযোগ দেয় এবং ক্যালিকে সমস্ত ক্যান্ডিডেট আসার জন্য অপেক্ষা না করেই কলটির উপর কাজ শুরু করতে ও একটি সংযোগ স্থাপন করতে সক্ষম করে।

সিগন্যালিংয়ের জন্য 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- এর মতো ভিডিও চ্যাট অ্যাপগুলোর ক্ষেত্রে, একটি কাস্টম লিঙ্ক শেয়ার করে অন্যদের কলে আমন্ত্রণ জানানো হয়। ডেভেলপার ক্রিস বল একটি আকর্ষণীয় সার্ভারলেস-ওয়েবআরটিসি এক্সপেরিমেন্ট তৈরি করেছেন, যা WebRTC কলের অংশগ্রহণকারীদের তাদের পছন্দের যেকোনো মেসেজিং সার্ভিস, যেমন ইনস্ট্যান্ট মেসেজিং (IM), ইমেল বা হোমিং পিজিয়নের মাধ্যমে মেটাডেটা আদান-প্রদান করতে সক্ষম করে।

আপনি কীভাবে একটি সিগন্যালিং পরিষেবা তৈরি করতে পারেন?

পুনরায় বলছি, সিগন্যালিং প্রোটোকল এবং পদ্ধতিগুলো WebRTC স্ট্যান্ডার্ড দ্বারা সংজ্ঞায়িত নয়। আপনি যা-ই বেছে নিন না কেন, ক্লায়েন্টদের মধ্যে সিগন্যালিং বার্তা এবং অ্যাপ ডেটা আদান-প্রদানের জন্য একটি মধ্যস্থতাকারী সার্ভার প্রয়োজন। দুর্ভাগ্যবশত, একটি ওয়েব অ্যাপ ইন্টারনেটে চিৎকার করে বলতে পারে না, "আমাকে আমার বন্ধুর সাথে সংযুক্ত করে দাও!"

সৌভাগ্যবশত, সিগন্যালিং মেসেজগুলো ছোট হয় এবং বেশিরভাগ ক্ষেত্রেই কলের শুরুতে আদান-প্রদান করা হয়। একটি ভিডিও চ্যাট সেশনের জন্য appr.tc দিয়ে পরীক্ষা করার সময়, সিগন্যালিং পরিষেবাটি মোট প্রায় ৩০-৪৫টি মেসেজ পরিচালনা করেছিল, যেগুলোর সবগুলোর মোট আকার ছিল প্রায় ১০ কিলোবাইট।

ব্যান্ডউইথের দিক থেকে তুলনামূলকভাবে কম চাহিদাসম্পন্ন হওয়ার পাশাপাশি, WebRTC সিগন্যালিং পরিষেবাগুলো খুব বেশি প্রসেসিং বা মেমরি ব্যবহার করে না, কারণ এদের কেবল বার্তা আদান-প্রদান করতে হয় এবং অল্প পরিমাণ সেশন স্টেট ডেটা, যেমন কোন ক্লায়েন্টগুলো সংযুক্ত আছে, তা ধরে রাখতে হয়।

সার্ভার থেকে ক্লায়েন্টে বার্তা পাঠান

Browser Support

  • ক্রোম: ৬।
  • প্রান্ত: ৭৯।
  • ফায়ারফক্স: ৬।
  • সাফারি: ৫।

Source

সংকেত প্রেরণের জন্য একটি বার্তা পরিষেবা দ্বিমুখী হওয়া প্রয়োজন: ক্লায়েন্ট-টু-সার্ভার এবং সার্ভার-টু-ক্লায়েন্ট। দ্বিমুখী যোগাযোগ HTTP-এর ক্লায়েন্ট/সার্ভার অনুরোধ/প্রতিক্রিয়া মডেলের পরিপন্থী, কিন্তু একটি ওয়েব সার্ভারে চলমান পরিষেবা থেকে ব্রাউজারে চলমান একটি ওয়েব অ্যাপে ডেটা পাঠানোর জন্য বহু বছর ধরে লং পোলিং- এর মতো বিভিন্ন কৌশল তৈরি করা হয়েছে।

EventSource এপিআই সার্ভার-সেন্ট ইভেন্ট সক্ষম করে, যা হলো HTTP-এর মাধ্যমে একটি ওয়েব সার্ভার থেকে ব্রাউজার ক্লায়েন্টে পাঠানো ডেটা। EventSource একমুখী মেসেজিংয়ের জন্য ডিজাইন করা হয়েছে, কিন্তু সিগন্যালিং মেসেজ আদান-প্রদানের জন্য একটি সার্ভিস তৈরি করতে এটিকে XHR-এর সাথে একত্রে ব্যবহার করা যেতে পারে। একটি সিগন্যালিং সার্ভিস কলারের কাছ থেকে আসা মেসেজকে, যা XHR রিকোয়েস্টের মাধ্যমে পাঠানো হয়, EventSource মাধ্যমে ক্যালির কাছে পাঠিয়ে দেয়।

Browser Support

  • ক্রোম: ৫।
  • প্রান্ত: ১২।
  • ফায়ারফক্স: ১১।
  • সাফারি: ৫।

Source

ওয়েবসকেট ফুল ডুপ্লেক্স ক্লায়েন্ট-সার্ভার যোগাযোগের জন্য ডিজাইন করা হয়েছে, যার অর্থ হলো মেসেজ একই সময়ে উভয় দিকে প্রবাহিত হতে পারে। বিশুদ্ধ ওয়েবসকেট বা সার্ভার-প্রেরিত ইভেন্ট ( EventSource ) দিয়ে তৈরি একটি সিগন্যালিং সার্ভিসের একটি সুবিধা হলো, এই এপিআইগুলোর ব্যাকএন্ড পিএইচপি, পাইথন এবং রুবির মতো ভাষার জন্য বেশিরভাগ ওয়েব-হোস্টিং প্যাকেজে প্রচলিত বিভিন্ন ওয়েব ফ্রেমওয়ার্কে প্রয়োগ করা যেতে পারে।

যেসব ব্রাউজার WebRTC সমর্থন করে, সেগুলো WebSocket-ও সমর্থন করে। সমস্ত সংযোগের জন্য TLS ব্যবহার করা উচিত, যাতে বার্তাগুলো এনক্রিপ্ট না করে আটকানো না যায় এবং প্রক্সি ট্র্যাভার্সালের সমস্যাও হ্রাস পায় । WebSocket এবং প্রক্সি ট্র্যাভার্সাল সম্পর্কে আরও তথ্যের জন্য, ইলিয়া গ্রিগোরিকের ' High Performance Browser Networking' বইয়ের WebRTC অধ্যায়টি পড়ুন।

আপনি WebRTC ক্লায়েন্টদের Ajax-এর মাধ্যমে একটি মেসেজিং সার্ভারকে বারবার পোল করিয়ে সিগন্যালিং পরিচালনা করতে পারেন, কিন্তু এর ফলে প্রচুর অপ্রয়োজনীয় নেটওয়ার্ক অনুরোধ তৈরি হয়, যা বিশেষ করে মোবাইল ডিভাইসের জন্য সমস্যাজনক। একটি সেশন প্রতিষ্ঠিত হওয়ার পরেও, অন্য পিয়ারদের দ্বারা কোনো পরিবর্তন বা সেশন বন্ধ হয়ে যাওয়ার ক্ষেত্রে সিগন্যালিং মেসেজের জন্য পিয়ারদের পোল করতে হয়। WebRTC Book অ্যাপের উদাহরণটি পোলিং ফ্রিকোয়েন্সির জন্য কিছু অপটিমাইজেশন সহ এই বিকল্পটি গ্রহণ করে।

স্কেল সিগন্যালিং

যদিও একটি সিগন্যালিং পরিষেবা প্রতি ক্লায়েন্টে তুলনামূলকভাবে কম ব্যান্ডউইথ এবং সিপিইউ ব্যবহার করে, একটি জনপ্রিয় অ্যাপের সিগন্যালিং সার্ভারগুলোকে বিভিন্ন স্থান থেকে আসা প্রচুর মেসেজ উচ্চ মাত্রার কনকারেন্সি সহ পরিচালনা করতে হতে পারে। যে WebRTC অ্যাপগুলোতে প্রচুর ট্র্যাফিক আসে, সেগুলোর জন্য এমন সিগন্যালিং সার্ভার প্রয়োজন যা উল্লেখযোগ্য লোড সামলাতে সক্ষম। আপনি এখানে বিস্তারিত বলেননি, কিন্তু উচ্চ-ভলিউম, উচ্চ-পারফরম্যান্স মেসেজিংয়ের জন্য বেশ কিছু বিকল্প রয়েছে, যার মধ্যে নিম্নলিখিতগুলো অন্তর্ভুক্ত:

  • এক্সটেনসিবল মেসেজিং অ্যান্ড প্রেজেন্স প্রোটোকল (XMPP) হলো ইনস্ট্যান্ট মেসেজিংয়ের জন্য তৈরি একটি প্রোটোকল যা সিগন্যালিংয়ের কাজেও ব্যবহার করা যায়। এর সার্ভার ইমপ্লিমেন্টেশনগুলোর মধ্যে রয়েছে ইজ্যাবার্ড (ejabberd) এবং ওপেনফায়ার (Openfire )। স্ট্রোফি.জেএস (Strophe.js )-এর মতো জাভাস্ক্রিপ্ট ক্লায়েন্টগুলো দ্বিমুখী স্ট্রিমিং অনুকরণ করতে BOSH ব্যবহার করে, কিন্তু ওয়েবসকেটের (WebSocket) তুলনায় BOSH অদক্ষ হতে পারে এবং এর স্কেলিং ক্ষমতাও দুর্বল।

  • ওপেন সোর্স লাইব্রেরি, যেমন ZeroMQ (যা TokBox তাদের Rumour সার্ভিসের জন্য ব্যবহার করে) এবং OpenMQ ( NullMQ, WebSocket-এর উপর STOMP প্রোটোকল ব্যবহার করে ওয়েব প্ল্যাটফর্মে ZeroMQ-এর ধারণাগুলো প্রয়োগ করে)।

  • বাণিজ্যিক ক্লাউড-মেসেজিং প্ল্যাটফর্মগুলো ওয়েবসকেট ব্যবহার করে (যদিও তারা প্রয়োজনে লং পোলিং ব্যবহার করতে পারে), যেমন পুশার এবং কাজিং

  • vLine- এর মতো বাণিজ্যিক WebRTC প্ল্যাটফর্মগুলি

নোডে Socket.io ব্যবহার করে একটি সিগন্যালিং সার্ভিস তৈরি করুন।

নিম্নলিখিতটি একটি ওয়েব অ্যাপের কোড, যা Node-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>

ক্লায়েন্টে উল্লেখিত জাভাস্ক্রিপ্ট ফাইল 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 Developer Tools-এর মাধ্যমে Ctrl+Shift+J (অথবা Mac-এ Command+Option+J ) চেপে কনসোলটি অ্যাক্সেস করতে পারেন।

সিগন্যালিংয়ের জন্য আপনি যে পদ্ধতিই বেছে নিন না কেন, আপনার ব্যাকএন্ড এবং ক্লায়েন্ট অ্যাপকে এই উদাহরণের মতো পরিষেবা প্রদান করতে হবে।

সিগন্যাল গটচাস

  • setLocalDescription() কল না করা পর্যন্ত RTCPeerConnection ক্যান্ডিডেট সংগ্রহ করা শুরু করবে না। JSEP IETF ড্রাফটে এটি বাধ্যতামূলক করা হয়েছে।
  • ট্রিকল আইস (Trickle ICE)-এর সুবিধা নিন। ক্যান্ডিডেট আসা মাত্রই addIceCandidate() কল করুন।

তৈরি সংকেত সার্ভার

আপনি যদি নিজে থেকে এটি তৈরি করতে না চান, তবে বেশ কিছু WebRTC সিগন্যালিং সার্ভার পাওয়া যায়, যেগুলো আগের উদাহরণের মতো Socket.IO ব্যবহার করে এবং WebRTC ক্লায়েন্ট জাভাস্ক্রিপ্ট লাইব্রেরির সাথে সমন্বিত থাকে:

আপনি যদি একেবারেই কোনো কোড লিখতে না চান, তাহলে vLine , OpenTok , এবং Asterisk-এর মতো কোম্পানিগুলোর কাছ থেকে সম্পূর্ণ বাণিজ্যিক WebRTC প্ল্যাটফর্ম পাওয়া যায়।

উল্লেখ্য যে, WebRTC-এর শুরুর দিকে এরিকসন অ্যাপাচিতে পিএইচপি ব্যবহার করে একটি সিগন্যালিং সার্ভার তৈরি করেছিল। এটি এখন কিছুটা অপ্রচলিত, কিন্তু আপনি যদি একই ধরনের কিছু করার কথা ভেবে থাকেন, তবে এর কোডটি দেখে নেওয়া যেতে পারে।

সংকেত নিরাপত্তা

সকল WebRTC উপাদানের জন্য এনক্রিপশন বাধ্যতামূলক

তবে, WebRTC স্ট্যান্ডার্ডে সিগন্যালিং পদ্ধতি সংজ্ঞায়িত করা নেই, তাই সিগন্যালিংকে সুরক্ষিত করার দায়িত্ব আপনারই। যদি কোনো আক্রমণকারী সিগন্যালিং ব্যবস্থাটি দখল করতে পারে, তবে তারা সেশন বন্ধ করে দিতে, সংযোগ অন্য পথে চালিত করতে এবং বিষয়বস্তু রেকর্ড, পরিবর্তন বা প্রবেশ করাতে পারে।

সিগন্যালিং সুরক্ষিত করার সবচেয়ে গুরুত্বপূর্ণ বিষয় হলো সুরক্ষিত প্রোটোকল ব্যবহার করা: HTTPS এবং WSS, যেমন TLS। এটি নিশ্চিত করে যে বার্তাগুলো এনক্রিপ্ট না করা অবস্থায় কেউ আটকাতে পারবে না। এছাড়াও, সিগন্যালিং বার্তাগুলো এমনভাবে সম্প্রচার না করার বিষয়ে সতর্ক থাকুন, যাতে একই সিগন্যালিং সার্ভার ব্যবহারকারী অন্য কলাররা সেগুলো অ্যাক্সেস করতে না পারে।

NAT এবং ফায়ারওয়াল মোকাবেলা করুন

মেটাডেটা সিগন্যালিংয়ের জন্য WebRTC অ্যাপগুলো একটি মধ্যস্থতাকারী সার্ভার ব্যবহার করে, কিন্তু একবার সেশন প্রতিষ্ঠিত হয়ে গেলে প্রকৃত মিডিয়া ও ডেটা স্ট্রিমিংয়ের জন্য RTCPeerConnection ক্লায়েন্টদের সরাসরি বা পিয়ার-টু-পিয়ার সংযোগ করার চেষ্টা করে।

আরও সরল একটি জগতে, প্রতিটি WebRTC এন্ডপয়েন্টের একটি অনন্য ঠিকানা থাকত, যা সে সরাসরি যোগাযোগের জন্য অন্যান্য পিয়ারদের সাথে বিনিময় করতে পারত।

সহজ পিয়ার টু পিয়ার সংযোগ
NAT এবং ফায়ারওয়াল ছাড়া একটি বিশ্ব

বাস্তবে, বেশিরভাগ ডিভাইস এক বা একাধিক NAT স্তরের আড়ালে থাকে, কোনো কোনোটিতে এমন অ্যান্টিভাইরাস সফটওয়্যার থাকে যা নির্দিষ্ট পোর্ট ও প্রোটোকল ব্লক করে দেয়, এবং অনেক ডিভাইস প্রক্সি ও কর্পোরেট ফায়ারওয়ালের আড়ালে থাকে। প্রকৃতপক্ষে, একটি ফায়ারওয়াল এবং NAT একই ডিভাইস দ্বারাও বাস্তবায়িত হতে পারে, যেমন বাড়ির ওয়াইফাই রাউটার।

NAT এবং ফায়ারওয়ালের পিছনে থাকা পিয়ারগুলি
বাস্তব জগৎ

WebRTC অ্যাপগুলো বাস্তব নেটওয়ার্কিং-এর জটিলতাগুলো কাটিয়ে উঠতে ICE ফ্রেমওয়ার্ক ব্যবহার করতে পারে। এটি সক্রিয় করতে, আপনার অ্যাপকে অবশ্যই RTCPeerConnection এ ICE সার্ভার URL-গুলো পাঠাতে হবে।

ICE পিয়ারদের সংযোগ করার জন্য সেরা পথ খুঁজে বের করার চেষ্টা করে। এটি সমান্তরালভাবে সমস্ত সম্ভাবনা যাচাই করে এবং সবচেয়ে কার্যকর বিকল্পটি বেছে নেয়। ICE প্রথমে একটি ডিভাইসের অপারেটিং সিস্টেম এবং নেটওয়ার্ক কার্ড থেকে প্রাপ্ত হোস্ট অ্যাড্রেস ব্যবহার করে সংযোগ স্থাপনের চেষ্টা করে। যদি সেটি ব্যর্থ হয় (যা NAT-এর পিছনে থাকা ডিভাইসগুলির ক্ষেত্রে ঘটবে), ICE একটি STUN সার্ভার ব্যবহার করে একটি এক্সটার্নাল অ্যাড্রেস সংগ্রহ করে এবং যদি সেটিও ব্যর্থ হয়, তবে ট্র্যাফিক একটি TURN রিলে সার্ভারের মাধ্যমে রাউট করা হয়।

অন্য কথায়, একটি STUN সার্ভার বাহ্যিক নেটওয়ার্ক অ্যাড্রেস পেতে ব্যবহৃত হয় এবং সরাসরি (পিয়ার-টু-পিয়ার) সংযোগ ব্যর্থ হলে ট্র্যাফিক রিলে করার জন্য TURN সার্ভার ব্যবহৃত হয়।

প্রতিটি TURN সার্ভার STUN সমর্থন করে। একটি TURN সার্ভার হলো এমন একটি STUN সার্ভার, যাতে অতিরিক্ত বিল্ট-ইন রিলেয়িং কার্যকারিতা থাকে। ICE, NAT সেটআপের জটিলতাগুলোও সামাল দেয়। বাস্তবে, NAT হোল-পাঞ্চিংয়ের জন্য শুধু একটি পাবলিক IP:port অ্যাড্রেসের চেয়েও বেশি কিছুর প্রয়োজন হতে পারে।

STUN এবং TURN সার্ভারগুলির জন্য URL-গুলি (ঐচ্ছিকভাবে) একটি 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 সেই তথ্য পেয়ে গেলে, ICE-এর জাদু স্বয়ংক্রিয়ভাবে ঘটে। RTCPeerConnection , প্রয়োজন অনুযায়ী STUN এবং TURN সার্ভারের সাথে কাজ করে, পিয়ারগুলোর মধ্যে সেরা পথ খুঁজে বের করার জন্য ICE ফ্রেমওয়ার্ক ব্যবহার করে।

স্টান

NAT একটি ডিভাইসকে একটি প্রাইভেট লোকাল নেটওয়ার্কের মধ্যে ব্যবহারের জন্য একটি আইপি অ্যাড্রেস প্রদান করে, কিন্তু এই অ্যাড্রেসটি বাইরে ব্যবহার করা যায় না। পাবলিক অ্যাড্রেস ছাড়া WebRTC পিয়ারদের মধ্যে যোগাযোগের কোনো উপায় থাকে না। এই সমস্যাটি এড়ানোর জন্য WebRTC, STUN ব্যবহার করে।

STUN সার্ভারগুলো পাবলিক ইন্টারনেটে থাকে এবং এদের একটিই কাজ: NAT-এর পেছনে চলমান কোনো অ্যাপ থেকে আসা আগত অনুরোধের IP:port ঠিকানা যাচাই করা এবং সেই ঠিকানাটিই প্রতিক্রিয়া হিসেবে ফেরত পাঠানো। অন্য কথায়, অ্যাপটি একটি পাবলিক দৃষ্টিকোণ থেকে তার IP:port খুঁজে বের করার জন্য একটি STUN সার্ভার ব্যবহার করে। এই প্রক্রিয়াটি একটি WebRTC পিয়ারকে নিজের জন্য একটি সর্বজনীনভাবে অ্যাক্সেসযোগ্য ঠিকানা পেতে এবং তারপর একটি সরাসরি সংযোগ স্থাপনের জন্য সিগন্যালিং পদ্ধতির মাধ্যমে অন্য একটি পিয়ারের কাছে তা প্রেরণ করতে সক্ষম করে।

STUN সার্ভারগুলোকে খুব বেশি কিছু করতে বা মনে রাখতে হয় না, তাই তুলনামূলকভাবে কম স্পেসিফিকেশনের STUN সার্ভারগুলোও বিপুল সংখ্যক অনুরোধ সামলাতে পারে।

STUN ব্যবহার করে বেশিরভাগ WebRTC কলই সফলভাবে সংযোগ স্থাপন করতে পারে, যদিও ফায়ারওয়াল এবং জটিল NAT কনফিগারেশনের পিছনে থাকা পিয়ারদের মধ্যে কলের ক্ষেত্রে এই হার কম হতে পারে।

STUN সার্ভার ব্যবহার করে পিয়ার-টু-পিয়ার সংযোগ
STUN সার্ভার ব্যবহার করে পাবলিক আইপি:পোর্ট অ্যাড্রেস পাওয়া

মোড় নিন

RTCPeerConnection পিয়ারদের মধ্যে UDP-এর মাধ্যমে সরাসরি যোগাযোগ স্থাপনের চেষ্টা করে। যদি তা ব্যর্থ হয়, RTCPeerConnection TCP ব্যবহার করে। যদি সেটাও ব্যর্থ হয়, তবে বিকল্প ব্যবস্থা হিসেবে TURN সার্ভার ব্যবহার করা যেতে পারে, যা এন্ডপয়েন্টগুলোর মধ্যে ডেটা আদান-প্রদান করে।

পুনরায় বলছি, TURN পিয়ারদের মধ্যে অডিও, ভিডিও এবং ডেটা স্ট্রিমিং রিলে করতে ব্যবহৃত হয়, ডেটা সিগন্যালিং করতে নয়!

TURN সার্ভারগুলোর পাবলিক অ্যাড্রেস থাকে, তাই পিয়াররা ফায়ারওয়াল বা প্রক্সির পেছনে থাকলেও তাদের সাথে যোগাযোগ করা যায়। TURN সার্ভারের একটিই কাজ: একটি স্ট্রিম রিলে করা। STUN সার্ভারের মতো নয়, এগুলো স্বভাবতই প্রচুর ব্যান্ডউইথ ব্যবহার করে।

STUN সার্ভার ব্যবহার করে পিয়ার-টু-পিয়ার সংযোগ
সম্পূর্ণ কৌশল: স্টান, টার্ন এবং সিগন্যালিং।

এই ডায়াগ্রামটি TURN-এর কার্যকারিতা দেখাচ্ছে। শুধুমাত্র STUN সফল হয়নি, তাই প্রতিটি পিয়ার একটি TURN সার্ভার ব্যবহার করতে বাধ্য হচ্ছে।

STUN এবং TURN সার্ভার স্থাপন করা

পরীক্ষার জন্য, গুগল একটি পাবলিক STUN সার্ভার ( stun.l.google.com:19302 ) চালায়, যা appr.tc দ্বারা ব্যবহৃত হয়। প্রোডাকশন STUN/TURN সার্ভিসের জন্য rfc5766-turn-server ব্যবহার করুন। STUN এবং TURN সার্ভারের সোর্স কোড গিটহাবে পাওয়া যায়, যেখানে আপনি সার্ভার ইনস্টলেশন সম্পর্কিত বিভিন্ন তথ্যের উৎসের লিঙ্কও খুঁজে পাবেন। অ্যামাজন ওয়েব সার্ভিসেসের জন্য একটি VM ইমেজও উপলব্ধ আছে।

একটি বিকল্প TURN সার্ভার হলো restund, যা সোর্স কোড হিসেবে এবং AWS-এর জন্যও উপলব্ধ। আপনি Compute-এ একটি restund সেট আপ করতে পারেন:

  1. প্রয়োজন অনুযায়ী tcp=443, udp/tcp=3478 এর জন্য ফায়ারওয়াল খুলুন।
  2. প্রতিটি পাবলিক আইপি-র জন্য একটি করে, স্ট্যান্ডার্ড উবুন্টু ১২.০৬ ইমেজের চারটি ইনস্ট্যান্স তৈরি করুন।
  3. স্থানীয় ফায়ারওয়াল কনফিগারেশন সেট আপ করুন (যেকোনো কিছু থেকে যেকোনো কিছুকে অনুমতি দিন)।
  4. টুল ইনস্টল করুন: shell sudo apt-get install make sudo apt-get install gcc
  5. creytiv.com/re.html থেকে libre ইনস্টল করুন।
  6. creytiv.com/restund.html থেকে restund ফাইলটি নিয়ে আসুন এবং আনপ্যাক করুন।
  7. wget hanke.name/restund-auth.patch এবং patch -p1 < restund-auth.patch দিয়ে প্রয়োগ করুন।
  8. make চালান, libre এবং restund-এর জন্য sudo make install
  9. আপনার প্রয়োজন অনুযায়ী restund.conf পরিবর্তন করুন (আইপি অ্যাড্রেসগুলো প্রতিস্থাপন করুন এবং নিশ্চিত করুন যে এতে একই শেয়ার্ড সিক্রেট রয়েছে) এবং /etc তে কপি করুন।
  10. restund/etc/restund ফাইলটিকে /etc/init.d/ -তে কপি করুন।
  11. ফেরত কনফিগার করুন:
    1. LD_LIBRARY_PATH সেট করুন।
    2. restund.conf /etc/restund.conf এ কপি করুন।
    3. সঠিক আইপি অ্যাড্রেস ব্যবহার করার জন্য restund.conf সেট করুন।
  12. রান রেস্টান্ড
  13. রিমোট মেশিন থেকে স্টান্ড ক্লায়েন্ট ব্যবহার করে পরীক্ষা করুন: ./client IP:port

মাল্টি-পার্টি ওয়েবআরটিসি

আপনি TURN সার্ভিস অ্যাক্সেস করার জন্য জাস্টিন উবার্টির প্রস্তাবিত REST API সংক্রান্ত IETF স্ট্যান্ডার্ডটিও দেখে নিতে পারেন।

মিডিয়া স্ট্রিমিংয়ের এমন অনেক ব্যবহার রয়েছে যা শুধু এক-একজনের ফোন কলের মধ্যেই সীমাবদ্ধ নয়। উদাহরণস্বরূপ, একদল সহকর্মীর মধ্যে ভিডিও কনফারেন্সিং অথবা এমন কোনো জনসভা যেখানে একজন বক্তার উপস্থিতিতে শত শত বা লক্ষ লক্ষ দর্শক অংশ নেন।

একটি WebRTC অ্যাপ একাধিক RTCPeerConnection ব্যবহার করতে পারে, যাতে একটি মেশ কনফিগারেশনে প্রতিটি এন্ডপয়েন্ট অন্য সব এন্ডপয়েন্টের সাথে সংযুক্ত হয়। talky.io- এর মতো অ্যাপগুলো এই পদ্ধতিই অনুসরণ করে এবং অল্প কিছু পিয়ারের জন্য এটি চমৎকারভাবে কাজ করে। এর বাইরে, প্রসেসিং এবং ব্যান্ডউইথের ব্যবহার অত্যধিক হয়ে পড়ে, বিশেষ করে মোবাইল ক্লায়েন্টদের জন্য।

মেশ: ছোট এন-ওয়ে কল
পূর্ণ মেশ টপোলজি: সবাই সবার সাথে সংযুক্ত

বিকল্পভাবে, একটি WebRTC অ্যাপ স্টার কনফিগারেশনে অন্য সব এন্ডপয়েন্টে স্ট্রিম বিতরণের জন্য একটি এন্ডপয়েন্ট বেছে নিতে পারে। এছাড়াও, একটি সার্ভারে WebRTC এন্ডপয়েন্ট চালানো এবং নিজস্ব পুনঃবন্টন ব্যবস্থা তৈরি করাও সম্ভব (webrtc.org একটি নমুনা ক্লায়েন্ট অ্যাপ সরবরাহ করে থাকে)।

একটি RTCPeerConnection থেকে MediaStream অন্যটির ইনপুট হিসেবে ব্যবহার করা যেতে পারে। এটি আরও নমনীয় আর্কিটেকচার তৈরি করতে পারে, কারণ এর মাধ্যমে একটি ওয়েব অ্যাপ কোন পিয়ারের সাথে সংযোগ স্থাপন করবে তা বেছে নিয়ে কল-রাউটিং পরিচালনা করতে পারে। এটি বাস্তবে দেখতে, WebRTC স্যাম্পলের 'Peer connection relay' এবং 'Multiple peer connections' দেখুন।

মাল্টিপয়েন্ট কন্ট্রোল ইউনিট

বহুসংখ্যক এন্ডপয়েন্টের জন্য একটি মাল্টিপয়েন্ট কন্ট্রোল ইউনিট (MCU) ব্যবহার করা একটি উন্নততর বিকল্প। এটি এমন একটি সার্ভার যা বহুসংখ্যক অংশগ্রহণকারীর মধ্যে মিডিয়া বিতরণের জন্য একটি সেতু হিসেবে কাজ করে। MCU-গুলো একটি ভিডিও কনফারেন্সে বিভিন্ন রেজোলিউশন, কোডেক এবং ফ্রেম রেট সামলাতে পারে; ট্রান্সকোডিং পরিচালনা করতে পারে; নির্দিষ্ট স্ট্রিম ফরওয়ার্ডিং করতে পারে; এবং অডিও ও ভিডিও মিশ্রিত বা রেকর্ড করতে পারে। মাল্টিপার্টি কলের ক্ষেত্রে বেশ কিছু বিষয় বিবেচনা করার থাকে, বিশেষ করে কীভাবে একাধিক ভিডিও ইনপুট প্রদর্শন করা যায় এবং একাধিক উৎস থেকে অডিও মিশ্রিত করা যায়। vLine- এর মতো ক্লাউড প্ল্যাটফর্মগুলোও ট্র্যাফিক রাউটিং অপ্টিমাইজ করার চেষ্টা করে।

একটি সম্পূর্ণ এমসিইউ হার্ডওয়্যার প্যাকেজ কেনা অথবা নিজেরটা নিজেই তৈরি করা সম্ভব।

সিসকো এমসিইউ৫৩০০ এর পশ্চাৎ দৃশ্য
সিসকো এমসিইউ- এর পিছনের অংশ

বেশ কিছু ওপেন সোর্স এমসিইউ সফটওয়্যার বিকল্প উপলব্ধ আছে। উদাহরণস্বরূপ, লিকোড (যা পূর্বে লিঙ্কিয়া নামে পরিচিত ছিল) ওয়েবআরটিসি-র জন্য একটি ওপেন সোর্স এমসিইউ তৈরি করে। ওপেনটকের রয়েছে ম্যান্টিস

ব্রাউজারের বাইরে: ভিওআইপি, টেলিফোন এবং মেসেজিং

WebRTC-এর প্রমিত প্রকৃতির কারণে ব্রাউজারে চলমান একটি WebRTC অ্যাপ এবং টেলিফোন বা ভিডিও-কনফারেন্সিং সিস্টেমের মতো অন্য কোনো যোগাযোগ প্ল্যাটফর্মে চালিত ডিভাইস বা প্ল্যাটফর্মের মধ্যে যোগাযোগ স্থাপন করা সম্ভব হয়।

SIP হলো VoIP এবং ভিডিও-কনফারেন্সিং সিস্টেমে ব্যবহৃত একটি সিগন্যালিং প্রোটোকল। একটি WebRTC ওয়েব অ্যাপ এবং একটি SIP ক্লায়েন্টের (যেমন একটি ভিডিও-কনফারেন্সিং সিস্টেম) মধ্যে যোগাযোগ স্থাপন করতে, সিগন্যালিং মধ্যস্থতার জন্য WebRTC-এর একটি প্রক্সি সার্ভারের প্রয়োজন হয়। সিগন্যালিং অবশ্যই গেটওয়ের মাধ্যমে প্রবাহিত হতে হবে, কিন্তু একবার যোগাযোগ স্থাপিত হয়ে গেলে, SRTP ট্র্যাফিক (ভিডিও এবং অডিও) পিয়ার-টু-পিয়ার পদ্ধতিতে প্রবাহিত হতে পারে।

পাবলিক সুইচড টেলিফোন নেটওয়ার্ক (PSTN) হলো সমস্ত সাধারণ অ্যানালগ টেলিফোনের সার্কিট-সুইচড নেটওয়ার্ক। WebRTC ওয়েব অ্যাপ এবং টেলিফোনের মধ্যে কলের জন্য, ট্র্যাফিককে অবশ্যই একটি PSTN গেটওয়ের মধ্য দিয়ে যেতে হয়। একইভাবে, WebRTC ওয়েব অ্যাপগুলোকে IM ক্লায়েন্টের মতো Jingle এন্ডপয়েন্টের সাথে যোগাযোগের জন্য একটি মধ্যবর্তী XMPP সার্ভারের প্রয়োজন হয়। মেসেজিং পরিষেবার জন্য ভয়েস এবং ভিডিও সক্ষম করতে XMPP-এর একটি এক্সটেনশন হিসেবে Google Jingle তৈরি করেছিল। বর্তমান WebRTC ইমপ্লিমেন্টেশনগুলো C++ libjingle লাইব্রেরির উপর ভিত্তি করে তৈরি, যা প্রাথমিকভাবে Talk-এর জন্য তৈরি করা Jingle-এর একটি ইমপ্লিমেন্টেশন।

বহু অ্যাপ, লাইব্রেরি এবং প্ল্যাটফর্ম বহির্বিশ্বের সাথে যোগাযোগের জন্য WebRTC-এর সক্ষমতা ব্যবহার করে। উদাহরণস্বরূপ:

  • jsSIP : জাভাস্ক্রিপ্ট এসআইপি লাইব্রেরি
  • ফোনো : একটি প্লাগইন হিসেবে নির্মিত ওপেন সোর্স জাভাস্ক্রিপ্ট ফোন এপিআই
  • টুইলিও : ভয়েস এবং মেসেজিং

আরও জানুন

৩৫০ পৃষ্ঠার বই ‘WebRTC: APIs and RTCWEB Protocols of the HTML5 Real-Time Web’-এ ডেটা ও সিগন্যালিং পাথওয়ে সম্পর্কে প্রচুর বিশদ তথ্য দেওয়া হয়েছে এবং এতে বেশ কিছু বিস্তারিত নেটওয়ার্ক টপোলজি ডায়াগ্রামও অন্তর্ভুক্ত রয়েছে।