Trước khi tìm hiểu về công nghệ thì bạn nhớ lại mình đã bao giờ dùng các công cụ audio/video call như là Google Hangouts chưa? Bạn đã tự hỏi làm sao họ làm được website video call mượt mà với nhiều người tham gia cùng một lúc như vậy?

Các ứng dụng đó được xây dựng xung quanh một công nghệ, gọi là WebRTC.

WebRTC là gì

WebRTC (Web Real-Time Communication) là một công nghệ cho phép các ứng dụng web sử dụng các P2P protocol để trao đổi dữ liệu giữa hai máy với nhau, cho phép các ứng dụng web thực hiện các cuộc gọi audio, video, truyền file, share màn hình,… mà không cần thêm bất kỳ sự hỗ trợ của một sản phẩm thứ ba nào khác, không cần cài đặt thêm bất kỳ một plugin nào.

WebRTC hiện vẫn đang được phát triển, nó được hỗ trợ ở hầu hết các Browser, tuy nhiên việc hỗ trợ đó không thực sự thống nhất. Một trong những giải pháp để giải quyết vấn đề này là dùng Adapter, bạn đọc thêm ở các tài liệu tham khảo ở cuối bài.

Bởi vì đây là công nghệ được hỗ trợ bởi trình duyệt, giúp hai trình duyệt ở hai điểm có thể tương tác với nhau mà không cần truyền tải dữ liệu lên server trung gian, điều đó giúp tín hiệu đi nhanh hơn, độ trễ thấp hơn, ứng dụng hoạt động hiệu quả hơn. Nó rất được ưa chuộng trong việc phát triển các sản phẩm hội thảo trực tuyến ngày nay.

Trước khi tìm hiểu về WebRTC APIs được hỗ trợ ở các Browser như thế nào, chúng ta nên tìm hiểu về cách mà 2 máy có thể nói chuyện trực tiếp được với nhau, nó là phần cốt lõi ở phía sau công nghệ này.

Khái niệm về các protocols

Private/Public IP

Các khái niệm tiếp theo nó liên quan mật thiết đến 2 khái niệm: private IP và public IP.

Lý thuyết phía sau của private/public IP khá là dài, bạn google sẽ thấy ngay, tại sao lại có khái niệm này, nó giải quyết vấn đề gì,…

Tuy nhiên có thể tóm tắt lại khái niệm này như sau: private IP là IP mạng cục bộ ví dụ mạng của 1 công ty, 2 mạng cục bộ có thể có cấu hình giống nhau và sẽ “không thấy” được nhau. Còn public IP dùng để xác định 1 host duy nhất trên Internet và nó là duy nhất.

ICE (Interactive Connectivity Establishment )

Thông thường hai máy tính ở trong hai mạng cục bộ (private) khác nhau sẽ không thể nói chuyện với nhau vì nhiều lý do, ICE là một kỹ thuật để giải quyết vấn đề đó, trong phạm vi bài này nó sẽ sử dụng STUN/TURN server để thực hiện việc đó.

NAT (Network Address Translation)

Là một phương pháp để chuyển đổi thông tin IP của một gói tin từ mạng cục bộ (private) sang mạng mạng công cộng (internet). NAT giúp các máy ở mạng cục bộ có thể nói chuyện được với các máy khác ở môi trường công cộng. Việc chuyển đổi thông tin gói tin từ mạng cục bộ sang mạng công cộng hay ngược lại được thực hiện ở router giao giữa 2 mạng đó.

STUN (Session Traversal Utilities for NAT)

Là một protocol phụ trợ cho các loại protocol khác khi làm việc với NAT. Nó cho phép xác định loại NAT, địa chỉ IP công cộng, port mà NAT đã cấp cho máy ở trong mạng cục bộ để kết nối đến. Hạn chế của STUN là không làm việc với Symmetric NAT. Để làm việc với STUN thì chúng ta phải có 1 STUN server trung gian được thấy ở các Peers.

 

 

 

 

TURN (Traversal Using Relays around NAT)

Tương tự STUN, TURN giúp khắc phục nhược điểm của STUN với Symmetric NAT, thay vì kết nối được thực hiện trực tiếp giữa 2 Peers thì mọi kết nối và trao đổi dữ liệu với TURN là thông qua một TURN server. Nhược điểm của phương án này là ở chỗ TURN server, ví dụ: khi bạn thực hiện video call với vài chục người mà phải truyền tải qua một server thì thực sự không ổn lắm.

 

 

SDP (Session Description Protocol)

SDP là một tiêu chuẩn mô tả nội dung được trao đổi khi kết nối như độ phân giải, mã hóa, định dạng,… nó giúp cho các Peer có một sự thống nhất khi trao đổi dữ liệu để có thể hiểu lẫn nhau.

Các khái niệm/API chính của WebRTC

Signaling Server

Ngay từ đầu bài viết đã nói WebRTC là công nghệ sử dụng các giao thức P2P để giao tiếp, vậy làm sao 2 máy có thể kết nối, giao tiếp với nhau? Trước khi các Peer có thể giao tiếp với nhau, chúng ta phải có một tầng trung gian nào đó để cài đặt kết nối giữa 2 máy đó hay nói cách khác chúng ta cần 1 server ở trung gian, server đó thường gọi là Signaling Server.

RTCPeerConnection

Là interface trong bộ WebRTC API được cung cấp bởi Browser, nó thể hiện kết nối WebRTC từ một máy local đến một máy remote, interface này cung cấp các phương thức để cho phép ứng dụng web tạo kết nối, duy trì kết nối, quan sát kết nối và đóng kết nối khi quá trình hội thoại kết thúc.

MediaStream

Là interface trong bộ WebRTC API được cung cấp bởi Browser, là interface thể hiện stream truyền tải dữ liệu giữa hai máy sau khi kết nối đã được thiết lập. Dữ liệu audio và video của cuộc hội thoại sẽ được truyền đi trong mỗi stream, đầu vào của máy local này chính là output của máy remote kia.

RTCDataChannel

Là interface trong bộ WebRTC API được cung cấp bởi Browser, sau khi kết nối được thiết lập, các kênh truyền dữ liệu sẽ được gán kết vào kết nối đó cho phép các Peer có thể thực hiện việc truyền dữ liệu với nhau thông qua các P2P protocol, theo lý thuyết thì mỗi kết nối có thể có đến 65,534 kênh dữ liệu được gắn kết vào. Tuy nhiên thực tế con số bao nhiêu thì nó phụ thuộc vào Browser.

Kiến trúc cơ bản của một ứng dụng WebRTC – P2P

Kiến trúc của một ứng dụng WebRTC (P2P) khá đơn giản, cách hoạt động của nó được mô tả qua các bước như sau:

1: Người dùng A gửi một thông điệp (offer SDP) lên Signaling server để nói rằng muốn nói chuyện với B.

2: Signaling server bằng một cách nào đó báo cho B biết là có A muốn nói chuyện.

3: B trả lời là chấp nhận (anwser SDP).

4: Signaling server báo cho A biết là B đã chấp nhận.

5: Kết nối được thiết lập giữa A và B, từ đây mọi trao đổi video, audio, file,… giữa A và B đều thông qua kết nối đã thiết lập.

Chi tiết hơn bạn xem các mô hình sau để biết tuần tự các bước thực hiện, các API được gọi để thiết lập một kết nối giữa hai máy như thế nào?

Ứng dụng mẫu

Hiện nay có rất nhiều open source hoàn chỉnh cho một ứng dụng WebRTC. Tuy nhiên trước khi bạn bắt đầu với các bộ source lớn đó bạn nên thử trải nghiệm với một bộ source nhỏ thuần túy dựa trên WebRTC API để hiểu rõ hơn về công nghệ này.

Source mẫu này các bạn có thể lấy từ https://github.com/lapth/FirebaseRTC.git, source được Fork từ https://github.com/webrtc/FirebaseRTC được cung cấp bởi http://webrtc.org.

Ở bài này tác giả chọn ví dụ mẫu dựa vào Firebase và Firebase Hosting để giảm thiểu quá trình nói về Signaling Server/Phần BE. Phần BE của mỗi ứng dụng WebRTC nó tùy vào yêu cầu thực tế không có một quy tắc chung nào.

Phần ứng dụng này khá nhỏ và dễ hiểu, ứng dụng gồm có 2 phần:

  1. Phần code liên quan đến quản lý ứng dụng WebRTC, bạn xem trong file public/app.js
    1. Bạn chú ý phần config của các STUN/TURN. Các server này chỉ dùng làm ví dụ, trong thực tế bạn cần có server riêng mà mình tin tưởng được.
    2. Code chính được viết trong 2 hàm createRoom và
    3. Nếu không quen thuộc với các câu lệnh Firebase các bạn có thể lướt qua, các bạn có thể hiểu nó như các câu lệnh CRUD của 1 RESTful.
  2. Phần UI, bạn xem ở file public/ index.html
  3. Các phần còn lại là config của Firebase và Hosting, bạn có thể bỏ qua.

Bản chạy thử:

Giải pháp nào cho hội thảo nhóm (Multiparty Video Conferencing)

Các phần trên của bài viết đã trình bày các khái niệm và kiến trúc cơ bản của một ứng dụng WebRTC ở mô hình P2P. Tiếp theo chúng ta tiếp tục cùng tìm hiểu các kiến trúc khác nhau cho bài toán hội thảo nhóm.

Mesh

Ở kiến trúc Mesh, các browser sẽ kết nối trực tiếp với nhau để truyền tải dữ liệu cho nhau. Mỗi browser sẽ truyền dữ liệu đi cho các browser còn lại đang tham gia nhóm, và nhận dữ liệu từ các browser truyền đến.

Ưu điểm: đơn giản, ít chi phí, hiệu quả với nhóm nhỏ, thường từ 4 đến 6 bên tham gia.

Nhược điểm: không thể áp dụng cho các nhóm lớn, phụ thuộc vào thiết bị ở mỗi Peer, lưu lượng upload/download dữ liệu ở mỗi Peer lớn.

MCU (Multipoint Conferencing Unit)

Khác với Mesh, ở giải pháp MCU các Peer sẽ gửi dữ liệu lên một server trung tâm, server trung tâm sau đó sẽ chịu trách nhiệm giải mã, trộn các stream nhận được từ các bên tham gia, sau đó mã hóa lại thành một stream duy nhất rồi truyền lại cho các bên.

Ưu điểm: giải quyết được nhược điểm của Mesh, không cần quá nhiều tài nguyên ở mỗi Peer.

Nhược điểm: yêu cầu server trung tâm phải đủ mạnh để giải mã, mã hóa lại dữ liệu của các bên tham gia với độ trễ thấp nhất.

SFU (Selective Forwarding Unit)

Và cuối cùng là kiến trúc SFU, ở kiến trúc này chúng ta vẫn cần có một server trung tâm, nhưng khác với kiến trúc MCU, nhiệm vụ của server này là để chuyển tiếp dữ liệu, khi nhận được dữ liệu của một stream nào đó, server trung tâm sẽ chuyển tiếp stream đó cho các bên tham gia khác.

Hiện tại đây là giải pháp khá tốt cho bài toán hội thảo nhóm lớn.

Về tính hiệu quả của ba giải pháp này, các bạn có thể tham khảo thêm report ở https://testrtc.com/different-multiparty-video-conferencing/

Tài liệu tham khảo

  1. https://webrtc.org/
  2. https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API
  3. https://jitsi.org/
  4. https://bloggeek.me/
  5. https://webrtcglossary.com/
  6. https://webrtchacks.com/sfu-cascading/
  7. https://testrtc.com/different-multiparty-video-conferencing/
  8. https://en.wikipedia.org/wiki/Network_address_translation
  9. https://en.wikipedia.org/wiki/STUN
  10. https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT
  11. https://en.wikipedia.org/wiki/Session_Description_Protocol
  12. https://tools.ietf.org/html/rfc2663
  13. https://tools.ietf.org/html/rfc5389
  14. https://tools.ietf.org/html/rfc5766
  15. https://tools.ietf.org/html/rfc8445

Bài viết đến đây là kết thúc, cám ơn các bạn đã đọc!

Trần Hữu Lập – FPT Software

Tin liên quan: