現在 IM 系統已經不僅限于文本消息的通訊了,多媒體數據占據越來越多的比重,比如:文件傳輸、語音通話、視頻通話等。
在前面的文章(《基于需求分析模型來結構化剖析 IM 系統》)中我們分析過,“多媒體消息” 屬于擴展功能需求,“點對點私信消息” 屬于基礎功能需求,擴展功能以基礎功能為基礎,基礎功能穩定實現后,開發擴展功能是非常簡單和快速的事情。今天我們分析一下 IM 系統的文件傳輸和語音通話功能關鍵邏輯實現,內容不復雜。
在前面關于分層架構 IM 系統所有文章的描述中,客戶端與服務端之間的通訊一直是基于一條 TCP 連接進行的,也就是單通道通訊。其實,在一個具備多種功能的 IM 產品中,前后端的通訊往往都是基于多通道的,也就是每個客戶端與服務端之間會建立多條連接(可能是 TCP 協議、也肯能是 HTTP 協議,還可能是 WebSocket 協議),為什么要這樣設計呢?
首先,每個通道傳輸自己專屬的數據,避免通道之間相互影響,產生阻塞或延遲,尤其是文本消息數據,需要一個專屬的通訊通道;我們知道多媒體數據往往會占用較大空間,如果通過文本消息通道傳輸多媒體數據的話,很容易影響文本消息的及時性和可靠性。
其次,每個通道傳輸自己專屬的數據,這從底層邏輯上就解耦了邏輯關聯,降低了整個系統實現的復雜性;我們在前面的文章(《架構師晉級:直播問答系統(解析)》)中,分析過直播問答系統如何通過多通道設計系統架構,降低復雜度。
下面,我們分別分析一下如何基于 IM 系統實現文件傳輸和語音通話。
一、文件傳輸
IM 系統的文件傳輸邏輯流程,見下圖。
基于 IM 系統傳輸文件,我們需要擴展消息的類型;最常見的消息類型是文本消息,可以擴展出文件消息類型、表情消息類型、語音消息類型、視頻消息類型等,只是在聊天窗口中需要以不同的方式進行展示。以客戶端 uid=101 給客戶端 uid=102 傳輸文件為例,文件傳輸的基本邏輯流程如下:
-
客戶端 uid=101 訪問 APPServer,獲取訪問令牌; APPServer 是需要搭建的內部服務,專門用來管理訪問令牌;令牌是客戶端用來訪問文件服務器(這里以對象存儲服務 OSS 為例)的憑證;APPServer 只給合法的客戶端發放令牌,畢竟 OSS 是收費的,只能供自己的客戶端產品使用。
-
客戶端 uid=101 憑訪問令牌,將文件上傳到 OSS,并記錄下文件的唯一標識,文件在 OSS 中的存儲位置(桶和目錄)。
-
客戶端 uid=101 將文件在 OSS 中存儲的相關信息(桶名稱、存儲目錄、文件標識等)封裝成 IM 消息,發送到 IM 服務端;這是 IM 消息發送的基本流程,在前面的文章(《分層架構 IM 系統之消息收發功能設計與實現》)中詳細分析過。
-
若客戶端 uid=102 處于在線狀態,IM 服務端會將文件消息直接推送到客戶端,這個過程通過 “三重保障” 實現消息的可靠性(《分層架構 IM 系統之消息收發功能設計與實現》);若客戶端 uid=102 處于離線狀態,待登錄后,會拉取相關離線消息。
-
客戶端 uid=102 通過解析,發現是文件消息類型后,請求 APPServer ,獲取訪問 OSS 的令牌。
-
客戶端 uid=102 憑訪問令牌,根據解析出的文件相關信息(桶名稱、存儲目錄、文件標識等)訪問 OSS,將客戶端 uid=101上傳的文件,下載到本地。
這就是基于 IM 系統進行文件傳輸的基本流程,第 3 和第 4 步,是消息收發的基本邏輯,以此為基礎引入文件存儲(OSS),集成和實現對文件存儲的安全訪問。
二、語音通話
IM 系統的語音通話邏輯流程,見下圖。
基于 IM 系統進行語音通話邏輯流程實現,與文件傳輸類型,都是以 IM 系統傳輸消息為基礎,集成語音通話服務(這里以 WChat 為例進行說明);客戶端 uid=101 給客戶端 uid=102 打語音電話,其基本的邏輯流程如下:
-
客戶端 uid=101 訪問 WChat,申請一個語音通話的房間,獲取房間標識和訪問令牌 voiceToken;房間是語音服務的一個邏輯概念,只有進入同一個房間的客戶端才能建立語音連接實現語音通話;WChat 建立 “房間” 后,該 “房間” 具有一定的時效性(比如:30秒),若對方沒有及時進入到 “房間”,“房間” 會失效;想一下,我們使用微信時通過語音呼叫對方的場景,很容易理解。
-
客戶端 uid=101 將房間標識信息封裝成 IM 消息,發送到 IM服務端;這是 IM 消息收發的基本邏輯。
-
若客戶端 uid=102 在線,IM 服務端直接將語音消息推送到客戶端;若客戶端 uid=102 離線,IM 系統需要通過其他方式(手機push、微信消息、短信等)及時通知到用戶。
-
客戶端 uid=102 通過解析,發現是語音消息類型后,向 IM 服務端發出獲取 voiceToken 的請求,IM 服務端會通過訪問 WChat 獲取語音會話令牌;為什么客戶端 uid=102 不直接訪問 WChat 獲取 voiceToken 呢? 一是為了安全性,只有申請房間的客戶端可以直接訪問 WChat,而要加入房間的客戶端,則需要訪問 IM 服務端,IM 過濾掉了加入房間的非法用戶;二是 WChat 中的房間具有時效性,要加入房間的客戶端在訪問 IM 時, IM 會對房間的時效性進行判斷,IM 過濾掉了沒有及時加入房間的用戶。
-
客戶端 uid=102 根據獲取的 voiceToken 和房間標識,訪問 WChat,加入房間,與客戶端 uid=101 建立語音會話。
不管是文件傳輸,還是語音通話,都是以 IM 消息通道為基礎,然后集成相關服務進行擴展。
最后,總結文中關鍵:
-
“點對點私信” 是基礎功能需求,“多媒體” 是擴展功能需求,基礎功能穩定實現后,開發擴展功能是非常簡單和快速的事情;
-
具備多種功能的 IM 產品中,前后端的通訊往往是基于多通道的,這樣設計的原因一是為了避免通道之間的相互影響,導致數據阻塞和延遲,二是為了降低實現的復雜度;
-
基于 IM 的文件傳輸邏輯,以 IM 消息通道為基礎,然后引入文件存儲服務,實現對文件存儲的安全訪問;
-
基于 IM 的語言通話邏輯,以 IM 消息通道為基礎,然后引入語音通話服務,實現對語音通話的安全訪問。