Apprtc 域名與ip訪問同一房間無法建立鏈接

前一陣同事架設webrtc Google官方演示 apprtc。 實際使用中發現了一個問題,使用域名訪問 和使用ip訪問 同一房間時無法建立鏈接。這裏就進行了一波debug,讀讀apprtc的源碼順便學習一波。

首先通過FireFox 的about:webrtc的方法查看webrtc Client 鏈接建立記錄發現ICE沒有得到得到對端SDP相關信息,當然這樣肯定無法建立鏈接啦。但是本地SDP相關信息均以拿到(公網ip等),看起來這就和Turn服務器 沒有太大的關係了。那問題應該是在房間服務器上。

繼續排查首先看下web_app生成的roomid是否一致。發現ip 和域名生活層的ip均一致。以域名作爲client端加入webrtc 某房間。另一端通過域名和ip 分別嘗試接入該房間。發現域名是執行Sending
answer to peer,成功建立鏈接。而ip則是Sending
offer to peer,且建立鏈接失敗。而問題原因大概找到了,以ip和域名 進入同一roomid的房間會被房間服務器認爲是不同房間。都會作爲init peer 執行Sending offer to peer等待了解。而在apprtc.debug.js
中可以找到如下函數:

 var joinPromise =

     this.joinRoom_().then(function(roomParams) {
       // The only difference in parameters should be clientId and isInitiator,
       // and the turn servers that we requested.
       // TODO(tkchin): clean up response format. JSHint doesn't like it.
       this.params_.clientId = roomParams.client_id;
       this.params_.roomId = roomParams.room_id;
       this.params_.roomLink = roomParams.room_link;
       this.params_.isInitiator = roomParams.is_initiator === 'true';
       console.info();
       this.params_.messages = roomParams.messages;
     }.bind(this)).catch(function(error) {
       this.onError_('Room server join error: ' + error.message);
       return Promise.reject(error);
     }.bind(this));

可以看到 roomParams.is_initiator 則爲房間服務器返回的是否是 房間初始節點的標誌位。以ip和域名訪問同一房間時,該標誌位均爲true。

看來問題是出在apprtc room服務器上,需要閱讀相應判斷是否爲同一房間的代碼,這部分代碼可以在out/apprtc.py 找到,在add_client_to_room 可以看到,apprtc 的所有room 是以某個key 存在memcache中。而key的生成規則爲下面的函數

def get_memcache_key_for_room(host, room_id):
  return '%s/%s' % (host, room_id)

所以真正原因找到,apprtc 對roomid 進行處理,在自身內部實現上真正用於存儲room相關info的key是以 請求host/roomid 的字符串。所以ip和域名請求同一房間被認爲是不同房間號。修復也很簡單(但目前還不知道後面會不會還有問題),僅以roomid作爲key即可。

def get_memcache_key_for_room(host, room_id):
  return '%s' % ( room_id)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章