跳至主要内容

HOW DISCORD HANDLES TWO AND HALF MILLION CONCURRENT VOICE USERS USING WEBRTC

Introduction

  • 這篇文章描述Discord如何建立聲音/影像多人溝通頻道,以及其背後用到的技術。
  • LINK

Guilding

聲音/影像多人溝通頻道需要支援多人(1000人)同時在線,因此比較適合使用Client-Server架構,Peer-to-Peer架構較不適合。

這裡的理解是如果使用P2P架構來實作多人頻道,假設頻道有N個使用者,則每個Client需與N-1個人建立連線,總共會有N*(N-1)個連線被建立。而這樣的花費非常高。

使用Client-Server架構還有個好處是Client的流量都會先經過Server Routing到其他Client,能夠避免Client的資訊被洩漏。

Client architecture

Discord跑在不同平台上

  • Web(Chrome/Firefox)
  • App(Windows/MacOS/Linux)
  • Phone(iOS/Android)

為了要支援跨平台的連線,Discord使用了WebRTC協定。WebRTC適合用於即時通訊,並且可以傳遞聲音、影像、資料等等資訊。

Discord的Web平台直接使用了WebRTC,而App和Phone平台則使用了基於WebRTC 函示庫程式碼的C++ Media Engine,增加了一些客製化的功能。這代表在App和Phone平台上能夠使用一些特殊功能。 舉例來說:

  • 抑制了Windows的 auto-ducking功能:
    • auto-ducking: 當在Windows使用通訊裝置時,會自動降低其他應用程式的音量。這對於在遊戲中溝通不太好。
  • 當頻道沒有聲音時,自動減少CPU使用率和網路頻寬。

然而使用客製化版本的WebRTC也代表,每當WebRTC更新時,客製化的函示庫可能也需要做一些調整。

Making it Our Own

這裡講述了一些客製化的詳細功能,並指出其與一般的WebRTC協定的差異。

  • WebRTC基於Session Description Protocol(SDP),用於一開始建立連線,傳送Participant的基本資訊。
    • 而客製化的Library可以使用較底層的Library function,來減少建立連線時傳遞的資訊。
  • WebRTC會透過 Interactive Connectivity Establishment (ICE) 來在Client之間傳遞訊息。
    • 客製化的Library不使用ICE,而是使用Discord自己的Relay Media Server。
  • WebRTC使用Secure RealTime Transport Protocol(SRTP),用來加密資訊。而加密方法使用Datagram Transport Layer Security(DTLS),一個基於TLS的方法。
    • 客製化的Library可以自己實作這些功能。而Discord使用了Salsa20用來更快的加密。

Backend Architecture

Discord後端建立了三種Server來服務頻道溝通,分別是:

  • Discord Gateway
  • Discord Guild Server
  • Discord Voice Server

    這些都是使用Elixir語言寫的。

當Client在線上時,會與Discord Gateway建立Websocket連線。

  • Client會從這個websocket連線中獲取最新的channel, guild等資訊。

當Client加入一個語音頻道時,Client會更新他的Voice state,並把最新資訊透過websocket連線傳送到Gateway。

接著,Client會被指定一個Voice Server並與他連線。語音頻道其他人的聲音會透過Voice Server傳到Client。

Note: 同個Guild中的所有Channel,會被連線到同個Voice Server。Guild 是由多個使用者組成的群組,裡面可以建立多個語音頻道。

  • 當此Client是第一個加入語音頻道的人,會由Guild Server指定一個新的Voice Server給他。

Assigning a Voice Server

  • 每個Voice Server會定期回報他的狀況,確保沒有斷線。而這些狀況資訊都會由一個Service Discovery Service接收並儲存,Discord使用 etcd
  • 當有新的連線被建立時,Discord Guild Server會透過Service Discovery service找出現在在線,而且使用率最低的Voice Server。
    • Guild Server同時會將連線資訊傳給Voice Server,也會把Voice Server資訊傳給Clients。
    • Client在收到資訊後會與新的Voice Server建立第二個WebSocket連線,用來與Voice Server傳遞建立連線相關的資訊。

Discord Voice Server由兩個Component組成:

  1. A Signaling Component
  2. SFU (selective forwarding Unit)
  • Signaling Component用來控制SFU,並負責產生加密密鑰,轉送資訊等等。

  • SFU負責轉送聲音及影像資訊給Clients。

    • SFU同時也負責管理RTCP(Real Time Control Protocol)
      • RTCP會蒐集Client的連線狀況,讓Server可以決定要轉送何種品質的聲音及影像資訊。