- ??歡迎點贊 :?? 收藏 ?留言 ?? 如有錯誤敬請指正,賜人玫瑰,手留余香!
- ??本文作者:由webmote 原創(chuàng)
- ??作者格言:新的征程,我們面對的不是技術而是人心,人心不可測,海水不可量,唯有技術,才是深沉黑夜中的一座閃爍的燈塔 !
序言
當下直播界最炙手可熱的技術,WebRTC應該時其中之一,而想在此技術領域登堂入室,確實有很多的知識和積累需要熟悉和學習,作為一個技術新手,怎么從懵懂到會用再到理解內涵而會心一笑,確實是挺難的一件事情。
也許我們永遠也無法企及大師的項背,但有一點可以堅信,只要我們努力去學習,會使用這個最簡單而直接的要求肯定能達到。
1. WebRTC技術
WebRTC(Web實時通信)是一種開放標準和技術,用于在Web瀏覽器之間實現(xiàn)實時通信,包括音頻、視頻和數(shù)據(jù)傳輸。它是由Google推出的,并得到了其他大型技術公司的支持和采用,目前眾多的瀏覽器都已經支持WebRTC了,因此其應用也越來越多。
WebRTC的主要特點包括:
-
實時通信:WebRTC允許實時的音頻、視頻和數(shù)據(jù)傳輸,使用戶可以通過瀏覽器直接進行語音和視頻通話,而無需其他插件或軟件。
-
網(wǎng)頁集成:WebRTC可以直接集成到Web瀏覽器中,通過JavaScript API進行操作,無需下載或安裝額外的應用程序。
-
點對點通信:WebRTC支持點對點(peer-to-peer)通信,這意味著數(shù)據(jù)可以直接在兩個瀏覽器之間傳輸,而無需通過中間服務器。這種直接的通信方式可以提高速度和減少延遲。
-
安全性:WebRTC使用安全的傳輸協(xié)議(如SRTP)來保護音頻和視頻通信的隱私和安全性。它還支持加密和身份驗證,確保通信的機密性和完整性。
-
開放標準:WebRTC是一個開放的標準,由W3C和IETF進行標準化和規(guī)范化。這意味著它是一個公開的技術,并且可以被廣泛采用和支持。
WebRTC技術的特點使其在在線會議、遠程協(xié)作、客戶支持和實時通信應用中得到廣泛應用。它提供了一種簡單、便捷和安全的方式來進行實時通信,為用戶提供了更好的體驗和互動性。
2. 信令服務
雖然WebRTC支持點對點通信,但它仍然需要服務器,以便客戶端可以交換元數(shù)據(jù),通過稱為信令的過程協(xié)調通信,并處理網(wǎng)絡地址轉換器(NAT)和防火墻。
這里我們主要介紹如何構建信令服務,以及如何處理與 STUN 和 TURN 服務器進行實際連接的行為。當然它還解釋了WebRTC應用程序如何處理多方呼叫并與VoIP和PSTN(也稱為電話)等服務進行交互。
如果您不熟悉WebRTC的基礎知識,請在閱讀本文之前參閱WebRTC入門。
那么,什么是信令呢?
信令是協(xié)調通信的過程。
為了使WebRTC應用程序能夠配置呼叫,其客戶端需要交換以下信息:
- 用于打開或關閉通信的會話控制消息
- 錯誤消息
- 多媒體元數(shù)據(jù),例如編解碼器、編解碼器設置、帶寬和媒體類型
- 用于建立安全連接的關鍵數(shù)據(jù)
- 網(wǎng)絡數(shù)據(jù),例如外界看到的主機的 IP 地址和端口
此信令過程需要和客戶端來回傳遞消息,該機制不是由WebRTC API實現(xiàn)的,您需要親自構建它。
2.1 為什么WebRTC沒有定義信令?
為了避免冗余并最大限度地與現(xiàn)有技術兼容,WebRTC標準沒有指定信令方法和協(xié)議。
JavaScript 會話建立協(xié)議 (JSEP
) 概述了此方法:
WebRTC呼叫背后的思想是完全指定和控制媒體,盡可能將信令留給應用程序。理由是不同的應用程序可能更喜歡使用不同的協(xié)議,例如現(xiàn)有的 SIP 或 Jingle 呼叫信令協(xié)議,或者針對特定應用程序自定義的內容。
JSEP 的體系結構還避免了瀏覽器必須保存狀態(tài),即充當信號狀態(tài)機的功能。例如,如果每次重新加載頁面時都會丟失信令數(shù)據(jù),這將是一個問題。相反,信令狀態(tài)可以保存在服務器上,這樣看起來架構就更完美了,下圖是JSEP體系架構。
JSEP 要求新的的交換在提問者offer
和 回答者answer
之間, 即上面提到的媒體元數(shù)據(jù)。Offer
和Answer
以會話描述協(xié)議 (SDP) 格式傳達,如下所示:
v=0
o=- 7614219274584779017 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:W2TGCZw2NZHuwlnf
a=ice-pwd:xdQEccP40E+P0L5qTyzDgfmW
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:9c1AHz27dZ9xPI91YNfSlI67/EMkjHHIHORiClQe
a=rtpmap:111 opus/48000/2
…
想知道所有這些SDP胡言亂語實際上意味著什么嗎?可以查看互聯(lián)網(wǎng)工程任務組 (IETF) 示例。
請記住,WebRTC的設計使得在通過編輯SDP文本中的值設置為本地或遠程描述之前可以調整offer
或answer
。例如,appr.tc 中的函數(shù)可用于設置默認編解碼器和比特率。
SDP用JavaScript操作起來有些痛苦,并且有關于WebRTC的未來版本是否應該使用JSON的討論,但是堅持使用SDP也有一些優(yōu)點。
2.2 Alice呼叫Eve
當Alice想要呼叫Eve時,使用WebRTC的過程大致如下:
-
Alice打開她的Web瀏覽器,并通過getUserMedia方法獲取她的音頻和視頻流。這將啟動她的攝像頭和麥克風。
-
Alice創(chuàng)建一個RTCPeerConnection對象,這是WebRTC中用于建立對等連接的主要對象。
-
Alice將她的本地流(音頻和視頻)添加到RTCPeerConnection對象中。
-
Alice創(chuàng)建一個數(shù)據(jù)通道(Data Channel),這是用于在對等連接之間傳輸任意數(shù)據(jù)的通道。數(shù)據(jù)通道可以用于發(fā)送文本消息、文件等。
-
Alice為數(shù)據(jù)通道設置消息接收的回調函數(shù),以便在收到來自Eve的消息時進行處理。
-
Alice創(chuàng)建一個offer(邀請),其中包含她的媒體信息和網(wǎng)絡配置。這個offer描述了Alice希望與Eve建立連接的條件。
-
Alice將她的本地描述(offer)設置為RTCPeerConnection的本地描述。
-
Alice通過信令服務器將她的本地描述發(fā)送給Eve。信令服務器充當中介,幫助Alice和Eve交換網(wǎng)絡配置和媒體信息。
-
Eve收到Alice的本地描述,并創(chuàng)建一個RTCPeerConnection對象。
-
Eve將她的本地流(音頻和視頻)添加到RTCPeerConnection對象中。
-
Eve將Alice的本地描述設置為她的RTCPeerConnection的遠程描述。
-
Eve創(chuàng)建一個answer(回答),其中包含她的媒體信息和網(wǎng)絡配置。這個answer是對Alice的offer的回應。
-
Eve將她的本地描述(answer)設置為RTCPeerConnection的本地描述。
-
Eve通過信令服務器將她的本地描述發(fā)送給Alice。
-
Alice收到Eve的本地描述,并將其設置為她的RTCPeerConnection的遠程描述。
-
Alice和Eve的RTCPeerConnection對象之間開始進行ICE(Interactive Connectivity Establishment)協(xié)商,以確定最佳的網(wǎng)絡連接路徑。
-
一旦ICE協(xié)商完成,Alice和Eve之間的對等連接建立成功,他們可以通過數(shù)據(jù)通道交換消息、音頻和視頻。
總的來說,WebRTC通過使用RTCPeerConnection對象和信令服務器來協(xié)調雙方之間的通信,使Alice能夠呼叫Eve并建立實時的音視頻通信。
JSEP 支持 ICE Candidate Trickling,它允許呼叫者在初始報價后以增量方式向被呼叫者提供候選人,并允許被呼叫者開始對呼叫執(zhí)行操作并建立連接,而無需等待所有候選人到達。
2.3 使用信令
看下代碼,如下:
// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription(await pc.createOffer());
// send the offer to the other peer
signaling.send({desc: pc.localDescription});
} catch (err) {
console.error(err);
}
};
// After remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
// Don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = event.streams[0];
};
// Call start() to initiate.
async function start() {
try {
// Get local stream, show it in self-view, and add it to be sent.
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({desc, candidate}) => {
try {
if (desc) {
// If you get an offer, you need to reply with an answer.
if (desc.type === 'offer') {
await pc.setRemoteDescription(desc);
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
await pc.setLocalDescription(await pc.createAnswer());
signaling.send({desc: pc.localDescription});
} else if (desc.type === 'answer') {
await pc.setRemoteDescription(desc);
} else {
console.log('Unsupported SDP type.');
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
更多詳細的代碼,可以參看一個例子程序。
2.4 發(fā)現(xiàn)對方
這是一種奇特的提問方式,我如何找到可以交談的人?
對于電話呼叫,您有電話號碼和目錄。對于在線視頻聊天和消息傳遞,您需要身份和狀態(tài)管理系統(tǒng),以及用戶啟動會話的方法。WebRTC應用程序需要一種方法,讓客戶端相互發(fā)出信號,表明他們想要開始或加入通話。
對等發(fā)現(xiàn)機制不是由WebRTC定義的,該過程可以像通過電子郵件發(fā)送或消息傳遞 URL 一樣簡單。對于視頻聊天應用(如對講和瀏覽器會議),您可以通過共享自定義鏈接來邀請他人加入通話。
2.5 如何構建信令服務
重申一下,信令協(xié)議和機制不是由WebRTC標準定義的。
無論您選擇什么,都需要一個中間服務器在客戶端之間交換信令消息和應用程序數(shù)據(jù)??杀氖牵W(wǎng)絡應用程序不能簡單地對互聯(lián)網(wǎng)大喊:“將我連接到我的朋友!”
值得慶幸的是,信令消息很小,主要在通話開始時交換。在視頻聊天會話的測試中,信令服務總共處理了大約 30-45 條消息,所有消息的總大小約為 10KB。
除了在帶寬方面相對不要求外,WebRTC信令服務不會消耗太多的處理或內存,因為它們只需要中繼消息并保留少量會話狀態(tài)數(shù)據(jù),例如連接了哪些客戶端。
2.6 將消息從服務器推送到客戶端
用于信令的消息服務必須是雙向的:客戶端到服務器和服務器到客戶端。
雙向通信違背了HTTP客戶端/服務器請求/響應模型,但是多年來已經開發(fā)了各種技術黑客行為,例如長輪詢,以便將數(shù)據(jù)從Web服務器上運行的服務推送到瀏覽器中運行的Web應用程序。
最近,EventSource API 已被廣泛實現(xiàn)。這將啟用服務器發(fā)送的事件 - 通過 HTTP 從 Web 服務器發(fā)送到瀏覽器客戶端的數(shù)據(jù)。 專為單向消息傳遞而設計,但它可以與 XHR 結合使用,以構建用于交換信令消息的服務。信令服務通過向被叫方推送消息來傳遞來自呼叫方的消息,該消息由 XHR 請求傳遞。
WebSocket 是一種更自然的解決方案,專為全雙工客戶端-服務器通信而設計 - 可以同時在兩個方向上流動的消息。使用純 WebSocket 或服務器發(fā)送的事件, 構建的信令服務的一個優(yōu)點是,這些 API 的后端可以在各種 Web 框架上實現(xiàn),這些框架是大多數(shù) Web 托管包(如 PHP、Python 和 Ruby)通用的。
當然,也可以通過讓WebRTC客戶端通過Ajax反復輪詢消息傳遞服務器來處理信令,但這會導致大量冗余的網(wǎng)絡請求,這對于移動設備來說尤其成問題。即使在建立會話后,對等方也需要輪詢信令消息,以防其他對等方更改或會話終止。
2.7 現(xiàn)成的信令服務器
如果你不想自己動手,有幾個WebRTC信令服務器可用,它們使用 Socket.IO ,并與WebRTC客戶端JavaScript庫集成:文章來源:http://www.zghlxwxcb.cn/news/detail-556496.html
- webRTC.io 是WebRTC最早的抽象庫之一。
- Signalmaster是為與SimpleWebRTC JavaScript客戶端庫一起使用而創(chuàng)建的信令服務器。
如果你根本不想寫任何代碼,可以從vLine,OpenTok和Asterisk等公司獲得完整的商業(yè)WebRTC平臺。文章來源地址http://www.zghlxwxcb.cn/news/detail-556496.html
到了這里,關于構建WebRTC技術需要的后端服務的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!