Introduction about Real time communication in Web (WebRTC)

1. Introduction

Dựa trên đặc điểm của dữ liệu và yêu cầu của dịch vụ, các dịch vụ trên internet được chia làm hai loại chính:

  • Dịch vụ thời gian thực (Real Time Service): cung cấp voice, video
  • Dịch vụ phi thời gian thực(Non Real Time Service): thường dùng chỉ để truyền dẫn dữ liệu thông thường

Các ứng dung dịch vụ thời gian thực nổi tiếng có thể kể đến là Skype, Webex, Sopcast ... và đa số các ứng này hoặc là độc lập hoặc sử dụng một extension của Web, và chưa thể tích hợp hoàn toàn với Web. Tuy nhiên, điều này đã dần thay đổi khi Google giới thiệu Google Hangout, một ứng thời gian thực dựa trên nền web có thể hoạt động tốt trên một trình duyệt web (Google Chrome). Trong bài blog này, mình sẽ giới thiệu sơ lược về WebRTC từ cấu trúc, các thức hoạt động và một số API chính của WebRTC.

2. Cấu trúc và cách thức hoạt động của WebRTC

2.1 Cấu trúc WebRTC

Về cơ bản, dữ liệu được truyền tải trên WebRTC là dữ liệu voice và video, tuy nhiên khác với các ứng dụng video stream điển hình như Youtube hay Vimeo là các định dạng video đã trải qua chế biến để có thể giảm bớt dụng lượng, các dữ liệu này phải được nhận và gửi trực tiếp từ các Media devices (Microphone, Webcam). Để có thể thực hiện điều này, một số trình duyệt Web đã thêm vào các module hỗ trợ multimedia, điển hình là Google Chrome, Moliza Firefox, Opera và một số trình duyệt khác trên thiết bị di động, chi tiết có thể tham khảo thêm tại CanIUse .

webrtcArchitecture.png

Để có thể tích hợp các ứng dụng thời gian thực vào web, các browser phải thêm vào các khối chức năng hỗ trợ dành cho WebRTC:

  • Voice/video engine: Thu nhận âm thanh và hình ảnh từ thiết bị ngoại vi (microphone, camera), điều chế mã hoá âm thanh và hình ảnh dựa trên các chuẩn mã hoá cơ bản trước khi truyền. Các chuẩn mã hoá cơ bản dành cho voice và video bao gồm: Opus, iSac, iLBC <voice>; VP8, H263, H264 (video).
  • Transport: cũng cấp chức năng kết nối với các thành phần khác cùng tham gia trong WebRTC (STUN, TURN, ICE ...)
  • Session management: đóng vai trò điều khiển hoạt động của ứng dụng
  • Application Programmable Interface - API: cung cấp các hàm cơ bản để các nhà phát triển có thể sử dụng. API ở đây có thể xét nằm trên 2 mức cơ bản: API dành cho Browser developer và API dành cho Front end developer.

Để có thể trải nghiêm tốt nhất WebRTC, chúng ta nên sử dụng trình duyệt Google Chrome khi mà trình duyệt này cung cấp gần như đầy đủ các API hỗ trợ dành cho WebRTC

2.2 Phương thức hoạt động

Trong mô hình hoạt động truyền thống của Web, mô hình client - server được sử dụng khá là phổ biến khi mà server sẽ đảm nhiệm tất cả bao gồm: điều khiển, truyền dữ liệu, security ... Tuy nhiên, nếu mang mô hình này vào trong các ứng dụng thời gian thực sẽ ảnh hướng tới hiệu năng hoạt động của ứng dụng vì các lý do sau:

  • Khối lượng dữ liệu trao đổi giữa các client là cực kỳ lớn. Chuẩn mã hoá voice OPUS có bitrate dao động từ 6 Kbps cho tới 510 Kbps. Nếu dữ liệu này truyền thằng trực tiếp tới server để server truyền tải tới client thì sẽ xảy ra việc quá tải không chỉ dành cho server mà cho cả hệ thống mạng.
  • Chất lượng dịch vụ (Quality of service - QoS). Trong QoS dành cho các ứng dụng thời gian thực, có hai tham số cực kỳ quan trọng cần được giảm thiểu tối đa là deplay (trễ client ) và jitter (trễ giữa các gói tin). Việc phải truyền tải toàn bộ dữ liệu tới server sẽ gia tăng rủi do trong delay và jitter.
  • Do đó, các ứng dụng thời gian thực đòi hỏi một mô hình khác có thể đáp ứng được hai yêu cầu trên, đó là mô hình Peer-to-Peer (P2P). Trong mô hình này, dữ liệu truyền tải được chia ra làm hai loại: dữ liệu điều khiển, báo hiệu (Signalling) và dữ liệu nội dung (Data stream). Các máy client thường sẽ giao tiếp với server để gửi/nhận các tín hiệu điều khiển và sau đó sẽ truyền nhận trực tiếp dữ liệu với các client khác.

jsep.png

Lấy một ví dụ đơn giản về Video chat sử dụng WebRTC:

  1. Caller và Callee khi bắt đầu sử dụng ứng dụng phải gửi các tín hiệu về về ứng dụng mà mình đang sử dụng tới server (session description)
  2. Caller gọi: Caller request tới server để đăng ký một cuộc gọi với Callee, server sẽ trả về cho Caller địa chỉ IP của Calle cùng với port ứng dụng hiện tại của Callee
  3. Callee sẽ nhận một bản tin của server báo về một cuộc gọi từ phái caller
  4. Caller bắt đầu truyền dữ liệu từ phía mình trực tiếp sang Callee
  5. Caller/callee ngắt kết nối: thông báo về server và dừng truyền dữ liệu

Tuy nhiên, trên thực tế, các peer đều sử dụng các địa chỉ IP private (thuộc các dải: 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8) và sử dụng cơ chế NAT để kết nối internet, do đó việc kết nối trực tiếp giữa các peer sẽ gặp khó khăn nếu sử dụng dải mạng nội bộ. Do đó, chúng ta phải có cơ chế hỗ trợ phân giải sang địa chỉ IP public.

STUN

stun.png

Để tiết kiệm địa chỉ IP, rất nhiều các nhà điều hành mạng sử dụng cơ chế NAT (Network address translation) để chuyển đổi từ địa chỉ IP mạng nội bộ sang địa chỉ IP Public. Về cơ bản địa chỉ IP sẽ được chuyển đổi như sau : IP private <-> IP public: port trong đó port ở đây là các cổng ứng dụng nằm trên Firewall hay router. Điều này giúp cho nhiều địa chỉ IP nội bộ có thể sử dụng chung IP public. STUN server sẽ đóng vai trò trung gian giúp cho các peer có thể lấy được địa chỉ của peer khác. Hiện nay, google đã xây dựng một số STUN server hỗ trợ hoàn toàn miễn phí như stun:stun.l.google.com:19302

TURN

turn.png

Trong mô hình OSI, tại lớp vận chuyển (Transport layer) có hai giao thức nổi tiếng là TCP và UDP. Trong khi UDP cung cấp khả năng vận chuyển nhanh nhất có thể thì TCP lại đảm bảo truyền tin cậy. Hầu hết trong các ứng dụng thời gian thực, tín hiệu điều khiển sẽ sử dụng TCP trong khi dữ liệu sẽ truyền bằng UDP. Tuy nhiên, UDP không phải là cơ chế truyền tin cậy, dễ làm tăng số lượng các gói tin bị mất (Packet lost), do vậy đôi khi TCP được ưu tiên sử dụng.

Ở đây, dữ liệu thay vì được gửi trực tiếp tới các peer thì các peer sẽ gửi dữ liệu tới các TURN server và TURN server sẽ đóng vai trò trung gian vận chuyển gói tin. Điều này nâng cao không những chất lượng dịch vụ của ứng dụng mà còn đảm bảo an toàn thông tin khi truyền dẫn.

2.3 Các API cơ bản

Trong phần này, một số API chính của WebRTC sẽ được giới thiệu

2.3.1 Hàm liên quan tới Media

getMedia = function(constraints,success) {
    if(!constraints) {
     constraints = {audio: true, video: true};
    }
    if(navigator.getUserMedia) {
     getUserMedia = navigator.getUserMedia.bind(navigator);
    }
    else if(navigator.webkitGetUserMedia) {
     console.log("webkit");
     getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
    }
}

Hàm này cho phép Web browser truy cập vào các thiết bị ngoại vi bao gồm microphone và camera, tuỳ theo các thiết bị mà developer muốn truy cập mà ta sẽ thiết lập constraints khác nhau

2.3.2 Hàm liên quan tới kết nối

  • Tạo một kết nối mới và thêm stream từ media device vào kết nối
   if( typeof(RTCPeerConnection) === "function") {
     peerConnection = new RTCPeerConnection(peerConfig);
   }
   else if( typeof(webkitRTCPeerConnection) === "function") {
     peerConnection = new webkitRTCPeerConnection(peerConfig);
   }
   peerConnection.addStream(myStream);
  • Tạo một lời đề nghị kết nối với peer khác bằng việc gửi session description:
    peerConnection.createOffer(function(SDP){
        peerConnection.setLocalDescription(SDP);
        console.log("sending offer to: "+roomId);
        var data = {
            type: "offer",
            roomId: roomId,
            payload: SDP
        };
        sendToServer(data);
    });
  • Nhận video của peer khác sau khi nhận được lời đều nghị (offer)
    peerConnection.onaddstream = function(e) {
        console.log("other guys stream added");
        otherStream = e.stream;
    }

2.3.3 Công cụ hỗ trợ dành cho developer

Ngoài việc cung cấp API, WebRTC còn cung cấp một số công cụ trên trình duyệt hỗ trợ người sử dụng kiểm tra hoạt động của WebRTC:

chrome://webrtc-internals
opera://webrtc-internals

3. Tham khảo

Trong quá trình tìm hiểu về WebRTC, tôi đã có thử xây dựng một dụng video chat sử dụng Ruby on Rails và Websocket (https://github.com/ducthien1490/webrtc-p2p). Trong ứng dụng này, tôi đã xây dựng WebRTC dựa trên server chính tại localhost, STUN server của Google. Để có thể thử trải nghiệm, người dùng nên thử mở ứng dụng bằng hai cửa sổ Google Chrome , một là cửa sổ bình thường, một là cửa sổ ở Incognito để phân biệt session một cách rõ ràng. Chi tiết về cách thức khởi tạo, có thể tham khảo tại README.md

http://www.html5rocks.com/en/tutorials/webrtc/basics/

http://www.webrtc.org/

https://www.youtube.com/watch?v=p2HzZkd2A40

http://io13webrtc.appspot.com

https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API

http://www.w3.org/TR/webrtc/

https://github.com/GoogleChrome/webrtc


All Rights Reserved