WebRTC通話INCOMPATIBLE_DESTINATION問題排查、verto與STUN協議

一個功能完整的WebRTC應用需要:
  • 使用GetUserMedia API 控制麥克風和攝像頭
  • 使用一種會話協議和可能的外部輔助服務器定位對方端點並建立會話
  • 使用ICE(和STUN和TURN)確定網絡路徑
  • 使用RTCPeerConnection 傳輸音/視頻媒體流
 
 
問題記錄:
脫機環境,沒有連接公網。網頁電話建立後,立即掛斷。SIP報錯信息:

488 Not Acceptable Here (INCOMPATIBLE_DESTINATION) 

 
排查過程:
首先想到了是WebRTC需要證書,因爲https和wss是WebRTC所需要的,瀏覽器對此有限制。於是自簽證書,在nginx上以ssl對證書進行認證。不過沒有解決問題。
其次,根據SIP信令狀態碼,推測原因有二,首先是編碼不兼容協商失敗,其次是地址問題,因爲WebRTC使用STUN處理防火牆穿透和NAT地址穿透。因此爲了對應這個問題在FreeSWITCH中追加IP地址是本機IP的acl條目,這個條目在conf/sip_profiles/internal.xml中加應該也可以
 
 配置文件路徑:conf/autoload_configs/verto.conf.xml ,追加內容:
<param name="apply-candidate-acl" value="192.168.71.137"/>
 
在此問題出現之前,已經加過的acl有如下:
 
               <param name="apply-candidate-acl" value="localnet.auto"/>                                                     
               <param name="apply-candidate-acl" value="wan_v4.auto"/>                                                       
               <param name="apply-candidate-acl" value="rfc1918.auto"/>                                                      
               <param name="apply-candidate-acl" value="any_v4.auto"/>
 
 
遺憾的是,仍然會有488 的問題。
 
隨後也嘗試了從STUN的角度解決問題。比如在本機搭建TURN服務,並且從WebRTC的javascript代碼中改iceServers內容。主要是對STUN不太熟悉,所以也不清楚是不是配置成功。最終也沒有解決488的問題。擱置。
 
那麼,回到問題本身,會不會是編碼原因?
freeswitch對webrtc通話提供了opus編碼,在生產環境、測試環境已經驗證可以使用。脫機環境使用了相同的系統以及配置,似乎這個是最不可能的原因。
爲了驗證問題,將fs提供的編碼改爲PCMA,沒想到的是通話媒體建立成功,並且應答以後沒有任何問題。
 
那真正的原因是什麼,恐怕不是編碼不支持這麼簡單。
爲何在無公網環境,opus不能使用?
 
第二天,將公司定製化的javascript包放到虛擬機的demo目錄,替換官方demo的verto-min.js包,使用軟電話呼叫webrtc坐席,使用成功,媒體建立成功。
到此,排除了fs和前端webrtc代碼問題。
 
說明下環境信息:
freeswitch地址: 172.16.10.40
瀏覽器地址:172. 16.10.171
 
在verto中 acl追加了一個項目,註釋掉其他所有的acl條目。
 
<param name="apply-candidate-acl" value="172.16.10.40"/>  
 
再打電話, 這時webrtc通話仍然報錯,錯誤碼不同,SIP狀態碼是480,前端顯示“CODEC ERROR”,freeswitch日誌中顯示“Temporarily unavailable” ,再結合在freeswitch的日誌中,有一行關鍵信息:
 
5d44774b-5331-455d-ac7e-18f8547c8b70 2020-05-20 15:15:44.503732 [DEBUG] switch_core_media.c:3567 verto.rtc/a0e5445a-d820-f2e0-ebe5-3d117ea12c64 no suitable candidates found.
據此推斷,這個candidate不光是指服務端,也應用在webrtc瀏覽器一端,於時修改acl條目:
<param name="apply-candidate-acl" value="172.16.10.0/24"/>
 
修改後重新加載verto模塊,再次呼叫。成功,媒體建立完成。前端出現“display”消息。
總結一下, poc環境,單個物理機上部署了多種服務,前端後端以及AI服務。AI服務使用了防火牆,在docker的多個虛擬網卡進行轉發。可能會影響了STUN服務的作用。因此webrtc找建立媒體通道失敗。
 
PS:
在本地虛擬機環境上,搭建了與poc相同的環境,前端使用fs官方發佈的demo代碼、公司定製化的verto.js包。
 
 
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章