WebRTC 實現(xiàn)Android點到點互連(含Demo)

背景簡介

WebRTC被譽為是web長期開源開發(fā)的一個新啟元辨泳,是近年來web開發(fā)的最重要創(chuàng)新顾翼。WebRTC允許Web開發(fā)者在其web應(yīng)用中添加視頻聊天或者點對點數(shù)據(jù)傳輸合愈,不需要復(fù)雜的代碼或者昂貴的配置颅崩。目前支持Chrome、Firefox和Opera吃引,后續(xù)會支持更多的瀏覽器筹陵,它有能力達(dá)到數(shù)十億的設(shè)備刽锤。

然而,WebRTC一直被誤解為僅適合于瀏覽器朦佩。事實上并思,WebRTC最重要的一個特征是允許本地和web應(yīng)用間的互操作,很少有人使用到這個特性语稠。

所以自然Android應(yīng)用也可以植入WebRTC宋彼。好處是什么?簡單來說就是你可以用很簡潔的代碼仙畦,在手機上實現(xiàn)點對點的視頻聊天或者數(shù)據(jù)傳輸输涕,點對點!點對點慨畸!點對點莱坎!重要的事情說三遍。

項目準(zhǔn)備

信令服務(wù)器代碼:https://github.com/matthewYang92/WebRtcServer(代碼改自ProjectRTC

  • 安裝Node.js
  • 進入項目根目錄寸士,命令行:npm install
  • 命令行:node app.js
  • 打開瀏覽器輸入127.0.0.1:3000檐什,見到WebRtcServer標(biāo)題,服務(wù)器ready

客戶端代碼:https://github.com/matthewYang92/WebRtcAndroidClient(代碼參考AndroidRTC項目)

  • 下載后直接AndroidStudio打開
  • WebRtcClient.java類中的mSocketAddress變量改成你服務(wù)器的ip端口3000
  • 安裝后啟動App碉京,如果服務(wù)器log顯示-- xxxxx joined --證明客戶端已連上服務(wù)器
  • 至少兩個客戶端連接到服務(wù)器之后厢汹,其中一端點擊init開始連接

如果你已經(jīng)成功跑通了Demo螟深,那么恭喜你已經(jīng)成功了一半谐宙,接下來我們分析下實現(xiàn)流程。

實現(xiàn)流程

一界弧、添加WebRTC庫依賴

compile 'org.webrtc:google-webrtc:1.0.+'

二凡蜻、初始化核心類PeerConnectionFactory

    PeerConnectionFactory.initialize(PeerConnectionFactory
            .InitializationOptions
            .builder(this)
            .createInitializationOptions());

三、創(chuàng)建PeerConnection對象

        peerConnection = factory.createPeerConnection(
                iceServers, //ICE服務(wù)器列表
                constraints, //MediaConstraints
                this); //Context

四垢箕、建立P2P連接通道

WebRTC是基于P2P的划栓,但在端與端之間的連接通道還沒建立起來之前,我們需要通過一個信令服務(wù)器為端與端之間傳遞信令建立通道条获。信令服務(wù)器要做的東西很簡單忠荞,就是將一端的信息透傳給另一端,步驟如下(以Demo為例):我們啟動A端與B端帅掘,通過SocketIO連接到信令服務(wù)器委煤,我們以A作為發(fā)送端,B為響應(yīng)端修档。

信令交換

  1. A向服務(wù)器發(fā)出init請求
  2. 服務(wù)器將A的init請求轉(zhuǎn)發(fā)給連接上服務(wù)器的其他端
  3. B收到init請求后碧绞,調(diào)用peerConnection.createOffer()方法創(chuàng)建一個包含SDP的offer信令
  4. offer信令創(chuàng)建成功后會調(diào)用SdpObserver監(jiān)聽中的onCreateSuccess()響應(yīng)函數(shù),在此處B通過peerConnection.setLocalDescription()方法將SDP賦予自己的PeerConnection對象吱窝,同時將offer信令發(fā)送給服務(wù)器
  5. 服務(wù)器將offer信令轉(zhuǎn)發(fā)給A端
  6. A收到offer信令后讥邻,調(diào)用peerConnection.setRemoteDescription()方法將B發(fā)過來的SDP賦予自己的PeerConnection對象迫靖,并調(diào)用peerConnection.createAnswer()方法創(chuàng)建一個answer信令
  7. answer信令創(chuàng)建成功后同樣會調(diào)用SdpObserver監(jiān)聽中的onCreateSuccess()響應(yīng)函數(shù),在此處A同樣通過peerConnection.setLocalDescription方法將SDP賦予自己的PeerConnection對象兴使,同時將answer信令發(fā)送給服務(wù)器
  8. 服務(wù)器將answer信令轉(zhuǎn)發(fā)給B端
  9. B收到A的answer信令后系宜,利用peerConnection.setRemoteDescription()方法將A發(fā)過來的SDP賦予自己的PeerConnection對象

設(shè)置Candidate

  1. PeerConnection.Observer監(jiān)聽會調(diào)用onIceCandidate()響應(yīng)函數(shù)并提供IceCandidate對象。然后將IceCandidate對象組成candidate信令發(fā)送給服務(wù)器
  2. 服務(wù)器將candidate信令轉(zhuǎn)發(fā)給連接上服務(wù)器的其他端
  3. 收到candidate信令后調(diào)用peerConnection.addIceCandidate()IceCandidate賦予自己的PeerConnection對象

至此Peer-to-Peer的連接已經(jīng)建立起來了

五鲫惶、使用DataChannel收發(fā)信息

  1. 初始化DataChannel對象

        /*
        DataChannel.Init 可配參數(shù)說明:
        ordered:是否保證順序傳輸蜈首;
        maxRetransmitTimeMs:重傳允許的最長時間;
        maxRetransmits:重傳允許的最大次數(shù)欠母;
         */
        DataChannel.Init init = new DataChannel.Init();
        dataChannel = peerConnection.createDataChannel("dataChannel", init);
    
  2. onDataChannel()回調(diào)中注冊消息回調(diào)

        dataChannel.registerObserver(this);
    
  3. 發(fā)送消息

        byte[] msg = message.getBytes();
        DataChannel.Buffer buffer = new DataChannel.Buffer(
                ByteBuffer.wrap(msg),
                false);
        dataChannel.send(buffer);
    
  4. onMessage()回調(diào)收消息

        ByteBuffer data = buffer.data;
        byte[] bytes = new byte[data.capacity()];
        data.get(bytes);
        String msg = new String(bytes);
    

六欢策、關(guān)于ICE服務(wù)

(以下內(nèi)容引用自http://blog.csdn.net/youmingyu/article/details/53192714,博主的文章對我?guī)椭级嗌吞剩浅8兄x)

如果在局域網(wǎng)內(nèi)踩寇,信令交換后就已經(jīng)可以傳遞媒體流了,但如果雙方不在同一個局域網(wǎng)六水,就需要進行NAT/防火墻穿透(我是在局域網(wǎng)下測試的俺孙,沒有穿透,但還是把這方面內(nèi)容介紹下)掷贾。

WebRTC使用ICE框架來保證穿透睛榄。ICE全名叫交互式連接建立(Interactive Connectivity Establishment),一種綜合性的NAT/FW穿越技術(shù),它是一種框架想帅,可以整合各種NAT/FW穿越技術(shù)如STUN场靴、TURN(Traversal Using Relay NAT 中繼NAT實現(xiàn)的穿透)。ICE會先使用STUN港准,嘗試建立一個基于UDP的連接旨剥,如果失敗了,就會去TCP(先嘗試HTTP浅缸,然后嘗試HTTPS)轨帜,如果依舊失敗ICE就會使用一個中繼的TURN服務(wù)器。使用STUN服務(wù)器穿透的結(jié)構(gòu)如下:

image.png

我們可以使用Google的stun服務(wù)器:stun:stun.l.google.com:19302(Google嘛衩椒,翻墻你懂得蚌父,當(dāng)然如果有精力可以自己搭建一個stun服務(wù)器),那么我們怎么把這個地址告訴WebRTC呢毛萌,還記得之前的iceServers嗎苟弛,就是在創(chuàng)建PeerConnection對象的時候需要的參數(shù),iceServers里面存放的就是進行穿透地址變換的服務(wù)器地址朝聋,添加方法如下(保險起見可以多添加幾個服務(wù)器地址嗡午,如果有的話):

        iceServers.add(new PeerConnection.IceServer("stun:stun.l.google.com:19302"));

參考

官網(wǎng)
Android之WebRTC介紹
WebRTC的Android2Android實現(xiàn)
NAT- STUN和TURN簡介

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市冀痕,隨后出現(xiàn)的幾起案子荔睹,更是在濱河造成了極大的恐慌狸演,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件僻他,死亡現(xiàn)場離奇詭異宵距,居然都是意外死亡,警方通過查閱死者的電腦和手機吨拗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門满哪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人劝篷,你說我怎么就攤上這事采转⊥胶樱” “怎么了进胯?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵辫塌,是天一觀的道長。 經(jīng)常有香客問我哈恰,道長只估,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任着绷,我火速辦了婚禮蛔钙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘荠医。我一直安慰自己吁脱,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布子漩。 她就那樣靜靜地躺著豫喧,像睡著了一般石洗。 火紅的嫁衣襯著肌膚如雪幢泼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天讲衫,我揣著相機與錄音缕棵,去河邊找鬼。 笑死涉兽,一個胖子當(dāng)著我的面吹牛招驴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播枷畏,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼别厘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拥诡?” 一聲冷哼從身側(cè)響起触趴,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤氮发,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后冗懦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體爽冕,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年披蕉,在試婚紗的時候發(fā)現(xiàn)自己被綠了颈畸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡没讲,死狀恐怖眯娱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情爬凑,我是刑警寧澤困乒,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站贰谣,受9級特大地震影響娜搂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吱抚,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一百宇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧秘豹,春花似錦携御、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凄贩,卻和暖如春誓军,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疲扎。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工昵时, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人椒丧。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓壹甥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親壶熏。 傳聞我的和親對象是個殘疾皇子句柠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容