Kurento實戰之四:應用開發指南

歡迎訪問個人GitHub

https://github.com/zq2599/blog_demos前端

內容:全部原創文章分類彙總及配套源碼,涉及Java、Docker、Kubernetes、DevOPS等;java

本篇概覽

  • 本文是《Kurento實戰》的第四篇,前面的文章中,我們先部署KMS再啓動官方demo,還把Kurento的重要概念都分類學習過,接下來要開始應用開發了;
  • 本文的主要內容是分析官方的<font color="blue">kurento-hello-world</font>項目,瞭解Kurento應用開發的基本流程和知識點,本文使用的代碼是官方發佈的6.15.0版本,地址:https://github.com/Kurento/ku...
  • 閱讀代碼時,若是能從總體上將劃分清楚功能模塊,再有針對性的逐個攻破細節,將會更高效的學習和理解源碼,接下來我們就按照Kurento官方的標準套路去拆分並逐個攻破;

如何劃分功能模塊

按照不一樣的職責劃分,整個代碼被拆分爲三部分:git

  1. WebSocket相關:WebSocket相關的通用處理,例如鏈接創建、關閉、異常的回調,業務邏輯的分發等;
  2. WebRTC信令相關:ICE、SDP相關的處理;
  3. 業務邏輯:若是說1和2表明的是WebRTC的通用處理,那麼剩下的就是如何使用Kurento來實現業務需求了,這部分的主要內容是業務應用使用Kurento官方client和KMS交互,控制KMS爲端側提供服務,交互方式以下圖:
    在這裏插入圖片描述
  • 按照上述方式將代碼作好拆分,劃定邊界,不管是閱讀官方demo仍是本身開發應用,都能條理清晰的應對,接下來一塊兒學習官方的hello-world源碼,看看一個完整的Kurento應用是如何開發出來的

WebSocket相關

最簡單的邏輯應該是通用的WebSocket處理了,我們先看這部分,複雜的稍後再說,Handler類中和WebSockert相關的邏輯以下:程序員

  1. 繼承自TextWebSocketHandler(只處理text類型的數據,對於二進制數據直接關閉會話);
  2. 重寫afterConnectionEstablished:WebSocket鏈接創建的回調,只打了一行日誌;
  3. 重寫handleTransportError:WebSocket發生異常時候的回調,僅關閉WebSocketSession;
  4. 重寫afterConnectionClosed:不論WebSocket是正常關閉仍是發生異常,此方法都會執行,邏輯也很簡單,就是調用stop方法,這個方法是用來釋放KMS資源的,有好幾處都會調用,咱們留到稍後和其餘處理KMS的地方一塊兒講;
  5. WebSockert部分最重要的代碼是handleTextMessage方法,裏面是收到前端數據時的處理邏輯:先把數據轉爲JsonObject對象,此對象的messageId字段有四種值,每一種id及其對應的處理方法以下表格所示:
messageId 處理方法 說明
PROCESS_SDP_OFFER handleProcessSdpOffer 收到前端SDPOffer數據後的處理邏輯
ADD_ICE_CANDIDATE handleAddIceCandidate 收到前端ICE數據後的處理邏輯
STOP handleStop HashMap刪除用戶數據,再遠程調用MediaPipeline.release
ERROR handleError HashMap刪除用戶數據,再遠程調用MediaPipeline.release
  1. 並非全部的應用都須要重寫上訴所有代碼,仍是以實際需求出發決定是否要重寫,以<font color="blue">kurento-one2one-call</font>項目爲例,只重寫了handleTextMessage和afterConnectionClosed,其餘的使用父類的便可,以下圖:

在這裏插入圖片描述

  1. 還有一個發送消息到瀏覽器側的sendMessage方法,以及發送錯誤信息的sendError方法;

信令相關

  • <font color="blue">kurento-hello-world</font>應用的功能是和KMS實現實時音視頻通訊,所以WebRTC標準的信令處理是必不可少的,惋惜Kurento官方並無對信令處理作太多封裝(也多是信令和不一樣的業務處理邏輯都不同,致使很差抽象),結果就是一堆信令處理的代碼散落在業務代碼中;
  • 就算業務和信令的處理代碼同時出如今Handler類中,只要熟悉WebRTC的信令處理流程,也很容易讀懂代碼,下圖結合了WebRTC標準的信令處理流程,對前端和服務端的代碼串聯在一塊兒就行分析,左邊是瀏覽器上執行的js代碼,右邊是服務端,這些代碼都用紅色箭頭標識了處於WebRTC信令處理流程的具體位置,至此,整個流程都清晰的展示出來:

在這裏插入圖片描述

  • 若是您在電腦或手機上看上圖以爲模糊,請下載原始文件,用<font color="blue">draw.io</font>打開,文件所在目錄是:https://github.com/zq2599/blo... ,文件名爲<font color="red">helloworld-flow.drawio</font>
  • 上圖列出了信令相關的全部代碼,等到看完這些,剩下的就是業務代碼了,也就是圖中紫色部分的<font color="blue">handleProcessSdpOffer</font>方法;github

    業務相關

  • <font color="blue">kurento-hello-world</font>應用是把本地攝像頭和麥克風數據傳到KMS,再從KMS取得這些數據在頁面展現,先看看官方是如何描述KMS pipeline的:

在這裏插入圖片描述

  • 從上圖可見pipeline邏輯很是簡單:只有一個WebRtcEndpoint,把本身的Src和Sink接上就完成了,我們來看看對應的代碼,在方法handleProcessSdpOffer中:
// 建立pipeline
    final MediaPipeline pipeline = kurento.createMediaPipeline();
    user.setMediaPipeline(pipeline);

    // 建立webRtcEndpoint
    final WebRtcEndpoint webRtcEp =
        new WebRtcEndpoint.Builder(pipeline).build();
    user.setWebRtcEndpoint(webRtcEp);

    // 本身的sink鏈接上本身的src
    webRtcEp.connect(webRtcEp);

    // ---- Endpoint configuration

    String sdpOffer = jsonMessage.get("sdpOffer").getAsString();
    
    // 註冊各種監聽,例如媒體資源狀態變化、ICE變化等
    // 經過websocket回覆SDP Offer
    initWebRtcEndpoint(session, webRtcEp, sdpOffer);

    log.info("[Handler::handleStart] New WebRtcEndpoint: {}",
        webRtcEp.getName());
    
    // ---- Endpoint startup
    // 取得ICE信息
    startWebRtcEndpoint(webRtcEp);
  • 再來看看中止WebRtc的stop方法,其實就是向KMS發送了release指令:
private void stop(final WebSocketSession session) {
    // Remove the user session and release all resources
    final UserSession user = users.remove(session.getId());
    if (user != null) {
      MediaPipeline mediaPipeline = user.getMediaPipeline();
      if (mediaPipeline != null) {
        log.info("[Handler::stop] Release the Media Pipeline");
        mediaPipeline.release();
      }
    }
  }

小結

以上就是整個<font color="blue">kurento-hello-world</font>的源碼分析,整個工程的代碼在拆分後再分析時,變得異常清晰和簡單:web

  1. WebSocket和常規的java開發無異,向標準靠攏便可;
  2. WebRTC相關代碼佔了較大比重,可是嚴格遵循了標準的信令流程,只要熟悉WebRTC就很容易閱讀和理解;
  3. 業務邏輯實際上是和業務需求相關聯的,這裏須要熟悉KMS提供的能力,才能充分發揮KMS的實例,而pipeline編排和各個element的使用,也會是我們後面文章的重點,用好這些element,打磨出更強大靈活的服務;

你不孤單,欣宸原創一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 數據庫+中間件系列
  6. DevOps系列

歡迎關注公衆號:程序員欣宸

微信搜索「程序員欣宸」,我是欣宸,期待與您一同暢遊Java世界...
https://github.com/zq2599/blog_demos
相關文章
相關標籤/搜索