สร้างบริการแบ็กเอนด์ที่จำเป็นสำหรับแอป WebRTC

การส่งสัญญาณคืออะไร

การส่งสัญญาณเป็นกระบวนการประสานการสื่อสาร เพื่อให้แอป WebRTC ตั้งค่าการโทรได้ ไคลเอ็นต์ของแอปจะต้องแลกเปลี่ยนข้อมูลต่อไปนี้

  • ข้อความควบคุมเซสชันที่ใช้เพื่อเปิดหรือปิดการสื่อสาร
  • ข้อความแสดงข้อผิดพลาด
  • ข้อมูลเมตาของสื่อ เช่น ตัวแปลงรหัส การตั้งค่าตัวแปลงรหัส แบนด์วิดท์ และประเภทสื่อ
  • ข้อมูลคีย์ที่ใช้สร้างการเชื่อมต่อที่ปลอดภัย
  • ข้อมูลเครือข่าย เช่น ที่อยู่ IP และพอร์ตของโฮสต์ตามที่โลกภายนอกเห็น

กระบวนการส่งสัญญาณนี้ต้องมีวิธีให้ลูกค้าส่งข้อความไปมา WebRTC API ไม่ได้ใช้กลไกดังกล่าว คุณจะต้องสร้างเอง คุณจะดูวิธีสร้างบริการส่งสัญญาณได้ในบทความนี้ แต่ก่อนอื่น คุณต้องมีบริบทเล็กน้อย

เหตุใด WebRTC จึงไม่ได้กำหนดการส่งสัญญาณ

มาตรฐาน WebRTC ไม่ได้ระบุวิธีการและโปรโตคอลการส่งสัญญาณเพื่อหลีกเลี่ยงความซ้ำซ้อนและเพื่อเพิ่มความเข้ากันได้กับเทคโนโลยีที่มีอยู่มากที่สุด แนวทางนี้ระบุไว้ในโปรโตคอลการสร้างเซสชัน JavaScript (JSEP)

สถาปัตยกรรมของ JSEP ยังช่วยให้เบราว์เซอร์ไม่ต้องบันทึกสถานะด้วย ซึ่งก็คือการทํางานเป็นสถานะการทำงานของเครื่องส่งสัญญาณ การดำเนินการนี้จะทำให้เกิดปัญหาได้ เช่น ข้อมูลสัญญาณจะหายไปทุกครั้งที่โหลดหน้าเว็บซ้ำ แต่ระบบจะบันทึกสถานะการแจ้งเตือนไว้ในเซิร์ฟเวอร์แทน

แผนภาพสถาปัตยกรรม JSEP
สถาปัตยกรรม JSEP

JSEP กำหนดให้มีการแลกเปลี่ยนข้อเสนอและคำตอบ ซึ่งเป็นข้อมูลเมตาของสื่อที่กล่าวถึงข้างต้นระหว่างคู่ค้า ระบบจะสื่อสารข้อเสนอและคำตอบในรูปแบบ Session Description Protocol (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 เช่น สามารถใช้ฟังก์ชัน preferAudioCodec() ใน appr.tc เพื่อตั้งค่าตัวแปลงรหัสและอัตราบิตเริ่มต้น SDP นั้นจัดการด้วย JavaScript ได้ค่อนข้างยาก และมีการพูดคุยกันว่า WebRTC เวอร์ชันในอนาคตควรใช้ JSON แทนหรือไม่ แต่การใช้ SDP ก็มีข้อดีบางประการ

RTCPeerConnection API และการส่งสัญญาณ: ข้อเสนอ คำตอบ และคำตอบที่เป็นไปได้

RTCPeerConnection คือ API ที่แอป WebRTC ใช้เพื่อสร้างการเชื่อมต่อระหว่างคู่สนทนา รวมถึงสื่อสารเสียงและวิดีโอ

ในการเริ่มต้นกระบวนการนี้ RTCPeerConnection มี 2 งานดังนี้

  • ตรวจสอบสภาพของสื่อในพื้นที่ เช่น ความละเอียดและความสามารถของโค้ดคิว ข้อมูลเมตานี้ใช้สำหรับกลไกการเสนอและตอบ
  • รับที่อยู่เครือข่ายที่เป็นไปได้สำหรับโฮสต์ของแอป ซึ่งเรียกว่าผู้สมัคร

เมื่อยืนยันข้อมูลในเครื่องแล้ว จะต้องแลกเปลี่ยนข้อมูลผ่านกลไกการส่งสัญญาณกับคู่สนทนาระยะไกล

สมมติว่า Alice พยายามโทรหา Eve กลไกการเสนอ/ตอบแบบเต็มมีรายละเอียดดังนี้

  1. Alice สร้างออบเจ็กต์ RTCPeerConnection
  2. Alice สร้างข้อเสนอ (คำอธิบายเซสชัน SDP) ด้วยเมธอด RTCPeerConnection createOffer()
  3. Alice โทรหา setLocalDescription() เพื่อเสนอข้อเสนอ
  4. Alice จะเปลี่ยนข้อเสนอเป็นสตริงและใช้กลไกการส่งสัญญาณเพื่อส่งไปยัง Eve
  5. Eve โทรหา setRemoteDescription() พร้อมข้อเสนอของ Alice เพื่อให้ RTCPeerConnection ทราบเกี่ยวกับการตั้งค่าของ Alice
  6. Eve โทรหา createAnswer() และระบบจะส่งคำอธิบายเซสชันในเครื่องซึ่งเป็นคำตอบของ Eve ไปยังการเรียกกลับสำเร็จของการดำเนินการนี้
  7. Eve ตั้งค่าคำตอบเป็นคำอธิบายเฉพาะตำแหน่งโดยเรียกใช้ setLocalDescription()
  8. จากนั้น Eve ใช้กลไกการส่งสัญญาณเพื่อส่งคำตอบที่เป็นสตริงไปยัง Alice
  9. Alice ตั้งค่าคำตอบของ Eve เป็นคำอธิบายเซสชันระยะไกลโดยใช้ setRemoteDescription()

Alice และ Eve ยังต้องแลกเปลี่ยนข้อมูลเครือข่ายด้วย คำว่า "การค้นหาผู้สมัคร" หมายถึงกระบวนการค้นหาอินเทอร์เฟซเครือข่ายและพอร์ตโดยใช้เฟรมเวิร์ก ICE

  1. Alice สร้างออบเจ็กต์ RTCPeerConnection ที่มีตัวแฮนเดิล onicecandidate
  2. ระบบจะเรียกใช้ตัวแฮนเดิลเมื่อเครือข่ายที่ตรงกับเกณฑ์พร้อมใช้งาน
  3. ในตัวแฮนเดิล Alice จะส่งข้อมูลผู้สมัครที่แปลงเป็นสตริงไปยัง Eve ผ่านช่องทางการรับส่งสัญญาณ
  4. เมื่อ Eve ได้รับข้อความเกี่ยวกับผู้สมัครจาก Alice เธอจะเรียกใช้ 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 และดูตัวอย่างวิดีโอแชทแบบหน้าเดียวในบันทึกคอนโซล หากต้องการข้อมูลเพิ่มเติม ให้ดาวน์โหลดการดัมพ์สัญญาณและสถิติ WebRTC ทั้งหมดจากหน้า about://webrtc-internals ใน Google Chrome หรือหน้า opera://webrtc-internals ใน Opera

การค้นหาแอปเทียบเท่า

นี่เป็นวิธีพูดว่า "ฉันจะหาคนคุยด้วยได้ที่ไหน"

สําหรับการโทร คุณจะมีหมายเลขโทรศัพท์และสมุดโทรศัพท์ สําหรับวิดีโอแชทและการรับส่งข้อความออนไลน์ คุณต้องมีระบบการจัดการข้อมูลระบุตัวตนและการแสดงข้อมูล และวิธีให้ผู้ใช้เริ่มเซสชัน แอป WebRTC ต้องมีวิธีให้ลูกค้าส่งสัญญาณให้กันและกันว่าต้องการเริ่มหรือเข้าร่วมการโทร

WebRTC ไม่ได้กำหนดกลไกการค้นหาคู่สนทนา และคุณไม่จำเป็นต้องเข้าไปที่ตัวเลือกนี้ กระบวนการนี้อาจง่ายเพียงส่งอีเมลหรือส่งข้อความ URL สำหรับแอปวิดีโอแชท เช่น Talky, tawk.to และ Browser Meeting คุณจะเชิญผู้อื่นให้เข้าร่วมการโทรได้โดยแชร์ลิงก์ที่กำหนดเอง นักพัฒนาซอฟต์แวร์ Chris Ball ได้สร้างการทดลอง serverless-webrtc ที่น่าสนใจซึ่งช่วยให้ผู้เข้าร่วมการโทรผ่าน WebRTC แลกเปลี่ยนข้อมูลเมตาผ่านบริการรับส่งข้อความใดก็ได้ที่ต้องการ เช่น IM, อีเมล หรือนกพิราบสื่อสาร

คุณสร้างบริการส่งสัญญาณได้อย่างไร

ขอย้ำอีกครั้งว่ามาตรฐาน WebRTC ไม่ได้กำหนดโปรโตคอลและกลไกการส่งสัญญาณ ไม่ว่าคุณจะเลือกวิธีใด คุณก็ต้องใช้เซิร์ฟเวอร์สื่อกลางเพื่อแลกเปลี่ยนข้อความการรับส่งสัญญาณและข้อมูลแอประหว่างไคลเอ็นต์ แต่น่าเสียดายที่เว็บแอปไม่สามารถพูดกับอินเทอร์เน็ตว่า "เชื่อมต่อฉันกับเพื่อน" ได้

แต่โชคดีที่ข้อความส่งสัญญาณมีขนาดเล็กและส่วนใหญ่จะแลกเปลี่ยนกันในช่วงเริ่มต้นการโทร ในการทดสอบด้วย appr.tc สำหรับเซสชันวิดีโอแชท บริการส่งสัญญาณจัดการข้อความทั้งหมดประมาณ 30-45 ข้อความ โดยมีขนาดรวมของข้อความทั้งหมดประมาณ 10 KB

นอกจากจะไม่ต้องใช้แบนด์วิดท์มากนักแล้ว บริการส่งสัญญาณ WebRTC ยังไม่ใช้หน่วยประมวลผลหรือหน่วยความจำมากนัก เนื่องจากต้องส่งต่อข้อความและเก็บข้อมูลสถานะเซสชันเพียงเล็กน้อย เช่น ข้อมูลว่าไคลเอ็นต์ใดเชื่อมต่ออยู่

พุชข้อความจากเซิร์ฟเวอร์ไปยังไคลเอ็นต์

บริการรับส่งข้อความสำหรับส่งสัญญาณต้องเป็นแบบ 2 ทิศทาง ได้แก่ ไคลเอ็นต์ไปยังเซิร์ฟเวอร์และเซิร์ฟเวอร์ไปยังไคลเอ็นต์ การสื่อสารแบบ 2 ทิศทางขัดต่อรูปแบบคำขอ/การตอบกลับไคลเอ็นต์/เซิร์ฟเวอร์ HTTP แต่มีการคิดค้นแฮ็กต่างๆ เช่น การโพลลิงแบบนาน ในช่วงหลายปีที่ผ่านมาเพื่อส่งข้อมูลจากบริการที่ทำงานบนเว็บเซิร์ฟเวอร์ไปยังเว็บแอปที่ทำงานในเบราว์เซอร์

เมื่อเร็วๆ นี้ EventSource API ได้รับการนำไปใช้งานอย่างแพร่หลาย ซึ่งจะเปิดใช้เหตุการณ์ที่เซิร์ฟเวอร์ส่ง ซึ่งเป็นข้อมูลที่ส่งจากเว็บเซิร์ฟเวอร์ไปยังไคลเอ็นต์เบราว์เซอร์ผ่าน HTTP EventSource ออกแบบมาสำหรับการรับส่งข้อความแบบทางเดียว แต่สามารถใช้ร่วมกับ XHR เพื่อสร้างบริการสำหรับการแลกเปลี่ยนข้อความสัญญาณได้ บริการส่งสัญญาณจะส่งข้อความจากผู้โทรซึ่งส่งผ่านคำขอ XHR โดยส่งผ่าน EventSource ไปยังผู้รับสาย

WebSocket เป็นโซลูชันที่ใช้งานได้ง่ายกว่า ซึ่งออกแบบมาเพื่อการสื่อสารแบบ Full Duplex ระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ ซึ่งก็คือข้อความที่ส่งได้ทั้งสองทิศทางพร้อมกัน ข้อดีอย่างหนึ่งของบริการส่งสัญญาณที่สร้างด้วย WebSocket ล้วนๆ หรือเหตุการณ์ที่เซิร์ฟเวอร์ส่ง (EventSource) คือสามารถติดตั้งใช้งานแบ็กเอนด์สําหรับ API เหล่านี้ในเฟรมเวิร์กเว็บที่หลากหลายซึ่งพบได้ทั่วไปในแพ็กเกจเว็บโฮสติ้งส่วนใหญ่สําหรับภาษาต่างๆ เช่น PHP, Python และ Ruby

เบราว์เซอร์สมัยใหม่ทั้งหมดยกเว้น Opera Mini รองรับ WebSocket และที่สำคัญกว่านั้นคือเบราว์เซอร์ทั้งหมดที่รองรับ WebRTC จะรองรับ WebSocket ด้วย ทั้งบนเดสก์ท็อปและอุปกรณ์เคลื่อนที่ คุณควรใช้ TLS สำหรับการเชื่อมต่อทั้งหมดเพื่อให้แน่ใจว่าข้อความจะไม่มีการดักรับโดยไม่มีการเข้ารหัส และเพื่อลดปัญหาเกี่ยวกับการข้ามพร็อกซี (ดูข้อมูลเพิ่มเติมเกี่ยวกับ WebSocket และการข้ามพร็อกซีได้ที่บท WebRTC ในเครือข่ายเบราว์เซอร์ที่มีประสิทธิภาพสูงของ Ilya Grigorik)

นอกจากนี้ คุณยังจัดการการส่งสัญญาณได้โดยให้ไคลเอ็นต์ WebRTC ทำการสำรวจเซิร์ฟเวอร์การรับส่งข้อความซ้ำๆ ผ่าน Ajax แต่วิธีนี้จะทำให้มีคำขอเครือข่ายซ้ำๆ จำนวนมาก ซึ่งจะทำให้เกิดปัญหากับอุปกรณ์เคลื่อนที่โดยเฉพาะ แม้หลังจากสร้างเซสชันแล้ว พาร์ทเนอร์ยังต้องตรวจสอบข้อความสัญญาณในกรณีที่มีการเปลี่ยนแปลงหรือพาร์ทเนอร์รายอื่นสิ้นสุดเซสชัน ตัวอย่างแอป WebRTC Book ใช้ตัวเลือกนี้พร้อมกับการเพิ่มประสิทธิภาพบางอย่างสำหรับความถี่ในการสำรวจ

การส่งสัญญาณการปรับขนาด

แม้ว่าบริการการรับส่งสัญญาณจะใช้แบนด์วิดท์และ CPU ต่อไคลเอ็นต์ค่อนข้างน้อย แต่เซิร์ฟเวอร์การรับส่งสัญญาณสําหรับแอปยอดนิยมอาจต้องจัดการข้อความจํานวนมากจากสถานที่ต่างๆ ที่มีการทำงานพร้อมกันในระดับสูง แอป WebRTC ที่มีการเข้าชมจำนวนมากต้องใช้เซิร์ฟเวอร์การรับส่งสัญญาณที่รองรับภาระงานจำนวนมาก คุณไม่จำเป็นต้องลงรายละเอียดในส่วนนี้ แต่มีตัวเลือกมากมายสำหรับการรับส่งข้อความจำนวนมากที่มีประสิทธิภาพสูง ซึ่งรวมถึงตัวเลือกต่อไปนี้

  • eXtensible Messaging and Presence Protocol (XMPP) หรือเดิมเรียกว่า Jabber ซึ่งเป็นโปรโตคอลที่พัฒนาขึ้นเพื่อการรับส่งข้อความทันทีที่สามารถใช้สำหรับการส่งสัญญาณ (การติดตั้งใช้งานเซิร์ฟเวอร์ ได้แก่ ejabberd และ Openfire ไคลเอ็นต์ JavaScript เช่น Strophe.js ใช้ BOSH เพื่อจำลองสตรีมมิงแบบ 2 ทิศทาง แต่ด้วยเหตุผลหลายประการ BOSH อาจไม่มีประสิทธิภาพเท่ากับ WebSocket และอาจปรับขนาดได้ไม่ดีด้วยเหตุผลเดียวกัน) (Jingle เป็นส่วนขยาย XMPP ที่เปิดใช้เสียงและวิดีโอ โปรเจ็กต์ WebRTC ใช้คอมโพเนนต์เครือข่ายและการรับส่งจากไลบรารี libjingle ซึ่งเป็นการใช้งาน Jingle เวอร์ชัน C++)

  • ไลบรารีโอเพนซอร์ส เช่น ZeroMQ (ตามที่ TokBox ใช้กับบริการ Rumour) และ OpenMQ (NullMQ ใช้แนวคิด ZeroMQ กับแพลตฟอร์มเว็บโดยใช้โปรโตคอล STOMP ผ่าน WebSocket)

  • แพลตฟอร์มการรับส่งข้อความผ่านระบบคลาวด์เชิงพาณิชย์ที่ใช้ WebSocket (แม้ว่าอาจใช้การเรียกข้อมูลแบบ Polling นานแทน) เช่น Pusher, Kaazing และ PubNub (นอกจากนี้ PubNub ยังมี API สำหรับ WebRTC ด้วย)

  • แพลตฟอร์ม WebRTC เชิงพาณิชย์ เช่น vLine

(คู่มือเทคโนโลยีเว็บแบบเรียลไทม์ของนักพัฒนาซอฟต์แวร์ Phil Leggetter มีรายการบริการและไลบรารีการรับส่งข้อความที่ครอบคลุม)

สร้างบริการส่งสัญญาณด้วย Socket.io ใน Node

ต่อไปนี้คือโค้ดสําหรับเว็บแอปง่ายๆ ที่ใช้บริการส่งสัญญาณที่สร้างด้วย Socket.io ใน Node การออกแบบ Socket.io ทำให้สร้างบริการเพื่อแลกเปลี่ยนข้อความได้ง่าย และ Socket.io เหมาะอย่างยิ่งกับการส่งสัญญาณ WebRTC เนื่องจากมีแนวคิดของห้องในตัว ตัวอย่างนี้ไม่ได้ออกแบบมาเพื่อปรับขนาดเป็นบริการส่งสัญญาณระดับเวอร์ชันที่ใช้งานจริง แต่เข้าใจง่ายสำหรับผู้ใช้จํานวนไม่มากนัก

Socket.io ใช้ WebSocket ที่มีทางเลือกสำรอง ได้แก่ การเรียกข้อมูลแบบ AJAX นาน การสตรีมแบบหลายส่วน AJAX, Forever Iframe และการเรียกข้อมูล JSONP มีการพอร์ตไปยังแบ็กเอนด์ต่างๆ แต่เวอร์ชัน Node ที่ใช้ในตัวอย่างนี้อาจเป็นที่รู้จักมากที่สุด

ในตัวอย่างนี้ไม่มี WebRTC ตัวอย่างนี้ออกแบบมาเพื่อแสดงวิธีสร้างการรับส่งสัญญาณในเว็บแอปเท่านั้น ดูบันทึกคอนโซลเพื่อดูสิ่งที่เกิดขึ้นเมื่อไคลเอ็นต์เข้าร่วมห้องและแลกเปลี่ยนข้อความ Codelab ของ 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-static สำหรับขั้นตอนนี้ เพียงแต่ใช้ในตัวอย่างนี้เท่านั้น)

หากต้องการเรียกใช้แอปนี้ใน localhost คุณต้องติดตั้ง Node, Socket.IO และ node-static คุณสามารถดาวน์โหลด Node จาก Node.js (การติดตั้งนั้นง่ายและรวดเร็ว) หากต้องการติดตั้ง Socket.IO และ node-static ให้เรียกใช้ Node Package Manager จากเทอร์มินัลในไดเรกทอรีแอป โดยทำดังนี้

npm install socket.io
npm install node-static

หากต้องการเริ่มเซิร์ฟเวอร์ ให้เรียกใช้คําสั่งต่อไปนี้จากเทอร์มินัลในไดเรกทอรีแอป

node server.js

เปิด localhost:2013 จากเบราว์เซอร์ เปิดแท็บหรือหน้าต่างใหม่ในเบราว์เซอร์ใดก็ได้ แล้วเปิด localhost:2013 อีกครั้ง หากต้องการดูสิ่งที่เกิดขึ้น ให้ตรวจสอบคอนโซล ใน Chrome และ Opera คุณจะเข้าถึงคอนโซลผ่านเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Google Chrome ได้ด้วย Ctrl+Shift+J (หรือ Command+Option+J ใน Mac)

ไม่ว่าคุณจะเลือกแนวทางใดสำหรับการส่งสัญญาณ แอปไคลเอ็นต์และแบ็กเอนด์ของคุณอย่างน้อยต้องให้บริการที่คล้ายกับตัวอย่างนี้

ข้อควรระวังเกี่ยวกับการส่งสัญญาณ

  • RTCPeerConnection จะไม่เริ่มรวบรวมผู้สมัครจนกว่าจะมีการเรียกใช้ setLocalDescription() ซึ่งเป็นไปตามข้อกำหนดในร่าง JSEP IETF
  • ใช้ประโยชน์จาก Trickle ICE โทรหา addIceCandidate() ทันทีที่ผู้สมัครมาถึง

เซิร์ฟเวอร์รับส่งสัญญาณสำเร็จรูป

หากไม่ต้องการสร้างเซิร์ฟเวอร์ส่งสัญญาณ WebRTC เอง คุณสามารถใช้เซิร์ฟเวอร์ส่งสัญญาณ WebRTC ที่มีอยู่หลายรายการ ซึ่งใช้ Socket.IO เช่นเดียวกับตัวอย่างก่อนหน้านี้และผสานรวมกับไลบรารี JavaScript ของไคลเอ็นต์ WebRTC

  • webRTC.io เป็นหนึ่งในไลบรารีการแยกชั้นแรกๆ สำหรับ WebRTC
  • Signalmaster เป็นเซิร์ฟเวอร์การรับส่งสัญญาณที่สร้างมาเพื่อใช้กับไลบรารีไคลเอ็นต์ JavaScript ของ SimpleWebRTC

หากไม่ต้องการแต่งโค้ดใดๆ เลย แพลตฟอร์ม WebRTC เชิงพาณิชย์ที่สมบูรณ์มีให้บริการจากบริษัทต่างๆ เช่น vLine, OpenTok และ Asterisk

โปรดทราบว่า Ericsson ได้สร้างเซิร์ฟเวอร์การรับส่งสัญญาณโดยใช้ PHP ใน Apache ในช่วงเริ่มต้นของ WebRTC วิธีการนี้ล้าสมัยไปแล้ว แต่คุณควรดูโค้ดนี้หากกำลังพิจารณาใช้วิธีการที่คล้ายกัน

ความปลอดภัยของการส่งสัญญาณ

"การรักษาความปลอดภัยคือศิลปะในการทำให้ไม่มีอะไรเกิดขึ้น"

Salman Rushdie

การเข้ารหัสต้องระบุสำหรับคอมโพเนนต์ WebRTC ทั้งหมด

อย่างไรก็ตาม มาตรฐาน WebRTC ไม่ได้กำหนดกลไกการส่งสัญญาณ คุณจึงต้องเป็นผู้ทำให้การส่งสัญญาณปลอดภัย หากผู้โจมตีลักลอบใช้สัญญาณได้ ก็จะหยุดเซสชัน เปลี่ยนเส้นทางการเชื่อมต่อ และบันทึก เปลี่ยนแปลง หรือแทรกเนื้อหาได้

ปัจจัยสําคัญที่สุดในการรักษาความปลอดภัยของการส่งสัญญาณคือการใช้โปรโตคอลที่ปลอดภัย เช่น HTTPS และ WSS (เช่น TLS) ซึ่งช่วยให้มั่นใจว่าข้อความจะไม่มีการดักรับโดยไม่เข้ารหัส นอกจากนี้ โปรดระมัดระวังอย่าออกอากาศข้อความการรับส่งสัญญาณในลักษณะที่ผู้โทรรายอื่นที่ใช้เซิร์ฟเวอร์การรับส่งสัญญาณเดียวกันเข้าถึงได้

หลังจากส่งสัญญาณแล้ว: ใช้ ICE เพื่อรับมือกับ NAT และไฟร์วอลล์

สําหรับการส่งสัญญาณข้อมูลเมตา แอป WebRTC จะใช้เซิร์ฟเวอร์สื่อกลาง แต่สําหรับสตรีมมิงสื่อและข้อมูลจริงเมื่อสร้างเซสชันแล้ว RTCPeerConnection จะพยายามเชื่อมต่อไคลเอ็นต์โดยตรงหรือแบบ Peer-to-Peer

ในโลกที่เรียบง่ายกว่านี้ อุปกรณ์ปลายทาง WebRTC ทุกเครื่องจะมีที่อยู่ที่ไม่ซ้ำกันซึ่งสามารถแลกเปลี่ยนกับอุปกรณ์ปลายทางอื่นๆ เพื่อสื่อสารโดยตรง

การเชื่อมต่อแบบเพียร์ต่อเพียร์ที่ง่ายดาย
โลกที่ไม่มี NAT และไฟร์วอลล์

ในทางปฏิบัติ อุปกรณ์ส่วนใหญ่อยู่หลัง NAT อย่างน้อย 1 ชั้น บางเครื่องมีซอฟต์แวร์ป้องกันไวรัสที่บล็อกพอร์ตและโปรโตคอลบางรายการ และอุปกรณ์จํานวนมากอยู่หลังพร็อกซีและไฟร์วอลล์ของบริษัท อุปกรณ์เดียวกันอาจใช้ไฟร์วอลล์และ NAT เช่น เราเตอร์ Wi-Fi ในบ้าน

Peer ที่อยู่เบื้องหลัง NAT และไฟร์วอลล์
โลกแห่งความเป็นจริง

แอป WebRTC สามารถใช้เฟรมเวิร์ก ICE เพื่อลดความซับซ้อนของเครือข่ายในชีวิตจริง หากต้องการให้การดำเนินการนี้เกิดขึ้น แอปของคุณต้องส่ง URL ของเซิร์ฟเวอร์ ICE ไปยัง RTCPeerConnection ตามที่อธิบายไว้ในบทความนี้

ICE จะพยายามค้นหาเส้นทางที่ดีที่สุดเพื่อเชื่อมต่อกับเพียร์ โดยจะลองใช้ตัวเลือกทั้งหมดพร้อมกันและเลือกตัวเลือกที่มีประสิทธิภาพสูงสุดซึ่งใช้งานได้ ICE จะพยายามเชื่อมต่อโดยใช้ที่อยู่โฮสต์ที่ได้รับจากระบบปฏิบัติการและการ์ดเครือข่ายของอุปกรณ์ก่อน หากไม่สำเร็จ (ซึ่งจะเป็นเช่นนั้นสำหรับอุปกรณ์ที่อยู่หลัง NAT) ICE จะรับที่อยู่ภายนอกโดยใช้เซิร์ฟเวอร์ STUN และหากไม่สำเร็จ ระบบจะกำหนดเส้นทางการรับส่งผ่านเซิร์ฟเวอร์รีเลย์ TURN

กล่าวคือ ระบบจะใช้เซิร์ฟเวอร์ STUN เพื่อรับที่อยู่เครือข่ายภายนอก และใช้เซิร์ฟเวอร์ TURN เพื่อส่งต่อการรับส่งข้อมูลหากการเชื่อมต่อโดยตรง (แบบ peer-to-peer) ไม่สำเร็จ

เซิร์ฟเวอร์ TURN ทุกเครื่องรองรับ STUN เซิร์ฟเวอร์ TURN คือเซิร์ฟเวอร์ STUN ที่มีฟังก์ชันรีเลย์เพิ่มเติมในตัว นอกจากนี้ ICE ยังจัดการกับความซับซ้อนของการตั้งค่า NAT ได้ด้วย ในทางปฏิบัติ การเจาะ NAT อาจต้องใช้มากกว่าแค่ที่อยู่ IP:พอร์ตสาธารณะ

แอป WebRTC จะระบุ URL สำหรับเซิร์ฟเวอร์ STUN และ/หรือ TURN (ไม่บังคับ) ในออบเจ็กต์การกําหนดค่า 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 ใช้เฟรมเวิร์ก ICE เพื่อหาเส้นทางที่ดีที่สุดระหว่างคู่สนทนา โดยทำงานร่วมกับเซิร์ฟเวอร์ STUN และ TURN ตามความจำเป็น

STUN

NAT จะให้ที่อยู่ IP แก่อุปกรณ์เพื่อใช้ในเครือข่ายภายในส่วนตัว แต่ที่อยู่นี้ใช้ภายนอกไม่ได้ หากไม่มีที่อยู่สาธารณะ Peer ของ WebRTC จะสื่อสารกันไม่ได้ WebRTC ใช้ STUN เพื่อแก้ปัญหานี้

เซิร์ฟเวอร์ STUN ทำงานบนอินเทอร์เน็ตสาธารณะและมีงานง่ายๆ เพียงอย่างเดียว นั่นคือ ตรวจสอบที่อยู่ IP:port ของคำขอขาเข้า (จากแอปที่ทำงานอยู่หลัง NAT) และส่งที่อยู่นั้นกลับเป็นการตอบกลับ กล่าวคือ แอปใช้เซิร์ฟเวอร์ STUN เพื่อค้นหา IP:port จากมุมมองสาธารณะ กระบวนการนี้ช่วยให้ Peer ของ WebRTC รับที่อยู่เข้าถึงได้แบบสาธารณะสําหรับตนเอง แล้วส่งต่อไปยัง Peer อื่นผ่านกลไกการส่งสัญญาณเพื่อสร้างลิงก์โดยตรง (ในทางปฏิบัติ NAT แต่ละประเภทจะทำงานแตกต่างกันไป และอาจมี NAT หลายเลเยอร์ แต่หลักการยังคงเหมือนเดิม)

เซิร์ฟเวอร์ STUN ไม่จำเป็นต้องทำงานหรือจำข้อมูลมากนัก ดังนั้นเซิร์ฟเวอร์ STUN ที่มีประสิทธิภาพต่ำจึงจัดการคำขอจำนวนมากได้

การโทรผ่าน WebRTC ส่วนใหญ่เชื่อมต่อโดยใช้ STUN ได้สำเร็จ 86% ตามข้อมูลของ Webrtcstats.com แต่อาจน้อยกว่านี้สำหรับการโทรระหว่างคู่สนทนาที่อยู่เบื้องหลังไฟร์วอลล์และการกำหนดค่า NAT ที่ซับซ้อน

การเชื่อมต่อแบบ Peer to Peer โดยใช้เซิร์ฟเวอร์ STUN
การใช้เซิร์ฟเวอร์ STUN เพื่อรับที่อยู่ IP:พอร์ตสาธารณะ

TURN

RTCPeerConnection พยายามตั้งค่าการสื่อสารโดยตรงระหว่างเพียร์ผ่าน UDP หากไม่สำเร็จ RTCPeerConnection จะเปลี่ยนไปใช้ TCP หากใช้ไม่ได้ คุณจะใช้เซิร์ฟเวอร์ TURN เป็นทางเลือกสำรองได้ โดยทำหน้าที่เป็นสื่อกลางในการรับส่งข้อมูลระหว่างปลายทาง

เราขอย้ำอีกครั้งว่า TURN ใช้เพื่อส่งต่อสตรีมมิงเสียง วิดีโอ และข้อมูลระหว่างคู่สนทนา ไม่ใช่เพื่อส่งสัญญาณข้อมูล

เซิร์ฟเวอร์ TURN มีที่อยู่สาธารณะเพื่อให้ผู้ใช้รายอื่นติดต่อได้แม้ว่าผู้ใช้รายนั้นจะอยู่หลังไฟร์วอลล์หรือพร็อกซีก็ตาม เซิร์ฟเวอร์ TURN มีงานที่เข้าใจได้ง่าย นั่นคือ การส่งต่อสตรีม อย่างไรก็ตาม ต่างจากเซิร์ฟเวอร์ STUN ตรงที่เซิร์ฟเวอร์เหล่านี้ใช้แบนด์วิดท์เป็นจำนวนมาก กล่าวคือ เซิร์ฟเวอร์ TURN จะต้องมีประสิทธิภาพมากขึ้น

การเชื่อมต่อแบบ Peer to Peer โดยใช้เซิร์ฟเวอร์ STUN
Full Monty: STUN, TURN และ Signaling

แผนภาพนี้แสดงการทำงานของ TURN STUN ล้วนๆ ไม่สำเร็จ ดังนั้นพาร์ทเนอร์แต่ละรายจึงหันมาใช้เซิร์ฟเวอร์ TURN

การติดตั้งใช้งานเซิร์ฟเวอร์ STUN และ TURN

สำหรับการทดสอบ Google เรียกใช้เซิร์ฟเวอร์ STUN สาธารณะ stun.l.google.com:19302 ตามที่ appr.tc ใช้ สำหรับบริการ STUN/TURN เวอร์ชันที่ใช้งานจริง ให้ใช้ rfc5766-turn-server ซอร์สโค้ดสำหรับเซิร์ฟเวอร์ STUN และ TURN มีอยู่ใน GitHub ซึ่งคุณจะเห็นลิงก์ไปยังแหล่งข้อมูลต่างๆ เกี่ยวกับการติดตั้งเซิร์ฟเวอร์ด้วย นอกจากนี้ยังมีอิมเมจ VM สำหรับ Amazon Web Services ด้วย

เซิร์ฟเวอร์ TURN ทางเลือกคือ restund ซึ่งมีให้บริการเป็นซอร์สโค้ดและสำหรับ AWS ด้วย วิธีการตั้งค่าการคืนเงินใน Compute Engine มีดังนี้

  1. เปิดไฟร์วอลล์ตามที่จำเป็นสำหรับ tcp=443, udp/tcp=3478
  2. สร้างอินสแตนซ์ 4 รายการ โดยให้แต่ละรายการใช้ IP สาธารณะ 1 รายการและอิมเมจ Ubuntu 12.06 มาตรฐาน
  3. ตั้งค่าไฟร์วอลล์ในเครื่อง (อนุญาตทุกรายการจากทุกที่)
  4. เครื่องมือสำหรับติดตั้ง shell sudo apt-get install make sudo apt-get install gcc
  5. ติดตั้ง Libre จาก creytiv.com/re.html
  6. ดึงข้อมูล restund จาก creytiv.com/restund.html และแตกไฟล์/
  7. wget hancke.name/restund-auth.patch แล้วใช้กับ patch -p1 < restund-auth.patch
  8. เรียกใช้ make, sudo make install สำหรับ libre และ restund
  9. ปรับ restund.conf ให้เหมาะกับความต้องการของคุณ (แทนที่ที่อยู่ IP และตรวจสอบว่า restund.conf มีข้อมูลลับที่แชร์เดียวกัน) แล้วคัดลอกไปยัง /etc
  10. คัดลอก restund/etc/restund ไปยัง /etc/init.d/
  11. กำหนดค่าการคืนเงิน
    1. ตั้งค่า LD_LIBRARY_PATH
    2. คัดลอก restund.conf ไปยัง /etc/restund.conf
    3. ตั้งค่า restund.conf ให้ใช้ 10 ที่ถูกต้อง ที่อยู่ IP
  12. เรียกใช้การคืนเงิน
  13. ทดสอบโดยใช้ไคลเอ็นต์การสตนด์บายจากเครื่องระยะไกล: ./client IP:port

มากกว่าแบบตัวต่อตัว: WebRTC แบบหลายฝ่าย

นอกจากนี้ คุณอาจต้องดูมาตรฐาน IETF ที่ Justin Uberti เสนอสำหรับ REST API เพื่อเข้าถึงบริการ TURN ด้วย

คุณสามารถจินตนาการถึงกรณีการใช้งานสตรีมมิงสื่อที่มากกว่าการโทรแบบตัวต่อตัวได้อย่างง่ายดาย เช่น การประชุมทางวิดีโอระหว่างกลุ่มเพื่อนร่วมงานหรือกิจกรรมสาธารณะที่มีผู้พูดคนเดียวและผู้ชมหลายร้อยหรือหลายล้านคน

แอป WebRTC สามารถใช้ RTCPeerConnection ได้หลายรายการเพื่อให้อุปกรณ์ปลายทางทุกเครื่องเชื่อมต่อกับอุปกรณ์ปลายทางทุกเครื่องในการกำหนดค่า Mesh นี่เป็นแนวทางที่แอปต่างๆ เช่น talky.io นำมาใช้ และได้ผลดีกับคู่แข่งเพียงไม่กี่ราย นอกจากนี้ การใช้แบนด์วิดท์และการประมวลผลจะมากเกินไป โดยเฉพาะสำหรับไคลเอ็นต์บนอุปกรณ์เคลื่อนที่

Mesh: การโทรแบบ N-Way ขนาดเล็ก
โทโพโลยีแบบ Full Mesh: ทุกคนเชื่อมต่อกับทุกคน

หรือแอป WebRTC อาจเลือกปลายทาง 1 รายการเพื่อกระจายสตรีมไปยังปลายทางอื่นๆ ทั้งหมดในการกำหนดค่าแบบดาวก็ได้ นอกจากนี้ คุณยังเรียกใช้ปลายทาง WebRTC บนเซิร์ฟเวอร์และสร้างกลไกการจัดจำหน่ายใหม่ของคุณเองได้ (webrtc.org มีตัวอย่างแอปไคลเอ็นต์ให้)

ตั้งแต่ Chrome 31 และ Opera 18 MediaStream จาก RTCPeerConnection หนึ่งสามารถใช้เป็นอินพุตของอีก RTCPeerConnection ได้ ซึ่งช่วยให้สถาปัตยกรรมมีความยืดหยุ่นมากขึ้น เนื่องจากช่วยให้เว็บแอปจัดการการกำหนดเส้นทางการโทรได้โดยเลือกคู่สนทนารายอื่นที่จะเชื่อมต่อด้วย หากต้องการดูตัวอย่างการทำงานนี้ โปรดดูตัวอย่าง WebRTC การเชื่อมต่อแบบสื่อกลางของคู่และตัวอย่าง WebRTC การเชื่อมต่อแบบสื่อกลางของคู่หลายราย

คอนโทรลยูนิตแบบหลายจุด

ตัวเลือกที่ดีกว่าสำหรับอุปกรณ์ปลายทางจํานวนมากคือการใช้ยูนิตควบคุมแบบหลายจุด (MCU) ซึ่งเป็นเซิร์ฟเวอร์ที่ทำหน้าที่เป็นบริดจ์เพื่อกระจายสื่อระหว่างผู้เข้าร่วมจำนวนมาก MCU สามารถรองรับความละเอียด ตัวแปลงรหัส และอัตราเฟรมที่แตกต่างกันในการประชุมทางวิดีโอ จัดการการแปลงรหัส ส่งต่อสตรีมแบบเลือก และผสมหรือบันทึกเสียงและวิดีโอ การโทรแบบหลายฝ่ายมีปัญหาหลายประการที่ต้องพิจารณา โดยเฉพาะอย่างยิ่งวิธีแสดงอินพุตวิดีโอหลายรายการและผสมเสียงจากหลายแหล่ง แพลตฟอร์มระบบคลาวด์ เช่น vLine ยังพยายามเพิ่มประสิทธิภาพการกำหนดเส้นทางการเข้าชมด้วย

คุณสามารถซื้อแพ็กเกจฮาร์ดแวร์ MCU ที่สมบูรณ์หรือจะสร้างเองก็ได้

มุมมองด้านหลังของ Cisco MCU5300
ด้านหลังของ Cisco MCU

มีตัวเลือกซอฟต์แวร์ MCU แบบโอเพนซอร์สหลายรายการ เช่น Licode (เดิมชื่อ Lynckia) ผลิต MCU แบบโอเพนซอร์สสำหรับ WebRTC OpenTok มี Mantis

นอกเหนือจากเบราว์เซอร์: VoIP, โทรศัพท์ และการรับส่งข้อความ

ลักษณะที่เป็นมาตรฐานของ WebRTC ทำให้สามารถตั้งค่าการสื่อสารระหว่างแอป WebRTC ที่ทำงานในเบราว์เซอร์กับอุปกรณ์หรือแพลตฟอร์มที่ทำงานบนแพลตฟอร์มการสื่อสารอื่น เช่น โทรศัพท์หรือระบบวิดีโอคอนเฟอเรนซ์

SIP เป็นโปรโตคอลการส่งสัญญาณที่ระบบ VoIP และการประชุมทางวิดีโอใช้ หากต้องการเปิดใช้การสื่อสารระหว่างเว็บแอป WebRTC กับไคลเอ็นต์ SIP เช่น ระบบการประชุมทางวิดีโอ WebRTC ต้องใช้พร็อกซีเซิร์ฟเวอร์เป็นตัวกลางในการส่งสัญญาณ การส่งสัญญาณต้องส่งผ่านเกตเวย์ แต่เมื่อการสื่อสารเริ่มต้นขึ้นแล้ว การรับส่งข้อมูล SRTP (วิดีโอและเสียง) จะส่งผ่านแบบเพียร์ต่อเพียร์ได้โดยตรง

เครือข่ายโทรศัพท์พื้นฐาน (PSTN) คือเครือข่ายแบบใช้วงจรสลับของโทรศัพท์อนาล็อก "แบบเก่าๆ" ทั้งหมด การโทรระหว่างเว็บแอป WebRTC กับโทรศัพท์ต้องส่งผ่านเกตเวย์ PSTN ในทํานองเดียวกัน เว็บแอป WebRTC ต้องมีเซิร์ฟเวอร์ XMPP ตัวกลางเพื่อสื่อสารกับปลายทาง Jingle เช่น ไคลเอ็นต์ IM Jingle เป็นโปรโตคอลที่ Google พัฒนาขึ้นเพื่อขยายความสามารถของ XMPP ให้รองรับเสียงและวิดีโอสำหรับบริการรับส่งข้อความ การใช้งาน WebRTC ปัจจุบันอิงตามไลบรารี libjingle ของ C++ ซึ่งเป็นการใช้งาน Jingle ที่พัฒนาขึ้นสำหรับ Talk มาตั้งแต่แรก

แอป ไลบรารี และแพลตฟอร์มจำนวนหนึ่งใช้ประโยชน์จากความสามารถของ WebRTC ในการสื่อสารกับโลกภายนอก ดังนี้

  • sipML5: ไคลเอ็นต์ SIP ที่ใช้ JavaScript แบบโอเพนซอร์ส
  • jsSIP: ไลบรารี SIP ของ JavaScript
  • Phono: Open Source JavaScript Phone API ที่สร้างขึ้นเป็นปลั๊กอิน
  • Zingaya: วิดเจ็ตโทรศัพท์ที่ฝังได้
  • Twilio: เสียงและการรับส่งข้อความ
  • Uberconference: conferencing

นักพัฒนาซอฟต์แวร์ sipML5 ได้สร้างเกตเวย์ webrtc2sip ด้วย Tethr และ Tropo ได้สาธิตเฟรมเวิร์กการสื่อสารสำหรับภัยพิบัติ "ในกระเป๋าเอกสาร" โดยใช้เซลล์ OpenBTS เพื่อเปิดใช้การสื่อสารระหว่างฟีเจอร์โฟนและคอมพิวเตอร์ผ่าน WebRTC นั่นคือการสื่อสารทางโทรศัพท์ที่ไม่มีผู้ให้บริการ

ดูข้อมูลเพิ่มเติม

Codelab ของ WebRTC มีวิธีการแบบทีละขั้นตอนในการสร้างแอปแชทวิดีโอและข้อความโดยใช้บริการส่งสัญญาณ Socket.io ที่ทำงานบน Node

การนำเสนอ WebRTC ของ Google I/O จากปี 2013 พร้อมหัวหน้าทีมเทคโนโลยี WebRTC อย่าง Justin Uberti

การนำเสนอ SFHTML5 ของ Chris Wilson - ข้อมูลเบื้องต้นเกี่ยวกับแอป WebRTC

หนังสือ 350 หน้าชื่อ WebRTC: APIs and RTCWEB Protocols of the HTML5 Real-Time Web มีรายละเอียดมากมายเกี่ยวกับเส้นทางข้อมูลและสัญญาณ รวมถึงมีแผนภาพโทโปโลยีเครือข่ายที่ละเอียด

WebRTC และ Signaling: สิ่งที่เราเรียนรู้ตลอด 2 ปีที่ผ่านมา - บล็อกโพสต์ของ TokBox เกี่ยวกับเหตุผลที่การไม่รวม Signaling ไว้ในข้อกำหนดเป็นแนวคิดที่ดี

คู่มือที่เป็นประโยชน์ในการสร้างแอป WebRTC ของ Ben Strong มีข้อมูลมากมายเกี่ยวกับโครงสร้างพื้นฐานและโทโปโลยีของ WebRTC

บท WebRTC ในเครือข่ายเบราว์เซอร์ที่มีประสิทธิภาพสูงของ Ilya Grigorik อธิบายสถาปัตยกรรม กรณีการใช้งาน และประสิทธิภาพของ WebRTC อย่างละเอียด