WebRTC简介

2025-05-26

WebRTC简介

嘿,希望你一切平安。今天我们来聊聊 WebRTC(Web 实时通信)。

WebRTC 允许您进行点对点实时通信,而无需打扰服务器。是的,您没看错,您可以进行点对点通信实时共享媒体流,例如音频、视频和任意数据。

WebRTC简介

我们该怎么做呢?

在我们讨论 WebRTC 之前,我们先来聊聊 Socket 连接。Web Socket 允许我们在客户端发送/接收我们已知的实时事件。我们与 Socket 服务器建立 Socket 连接,然后就可以向服务器广播/接收事件了。

我们连接到服务器。假设有两个客户端(Peer)连接到服务器。因此,通信是通过服务器进行的。服务器负责建立该套接字连接。

由于这个原因,对等点有时可能会遇到连接问题、消息丢失和消息延迟。

这就像魔术一样吗?

稍等一下,在我们向对等方发送任何数据之前,我们需要建立连接,这对于开发人员在两个对等方之间建立 WebRTC 连接是一项具有挑战性的任务

信号

信令是双方为了建立连接而交换信息的方式。这些信息包含 SDP、ICE 候选、用户信息等。

信号传输可以通过套接字、实时数据库(如 Firestore 等)进行。

您可以随时制定信令逻辑来建立跨同行的连接。

如何建立联系?谈判

该流程从提出报价开始。

  1. Peer A 创建 Offer以便与 Peer B 进行通信。
  2. Peer B 需要接受该 offer并发回 Offer 的 Answer。
  3. 同伴 A 接受答案。

这个过程被称为谈判。

协商是双方协商他们想要交换哪种数据(即媒体流、任意数据)以及在两个设备之间交换数据的最佳方式的过程。

一般而言,在对等体之间建立连接之前,协商会让对等体决定他们想要交换什么类型的数据。

SDP(会话描述协议)

提供/应答协议 (Offer/Answer) 被称为SDP(会话描述协议)。SDP是一种描述跨端多媒体连接和会话的格式。您可以将 SDP 视为基于浏览器的普通会话。

new RTCPeerConnection().createOffer();
// Output of below code SDP Offer
{
    "type": "offer",
    "sdp": "v=0\r\no=- 6306366628372337755 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\n"
}
Enter fullscreen mode Exit fullscreen mode

一旦谈判完成,同行们现在就可以相互沟通。

好的!现在显示一些代码。

现在该写一些代码了。我们将在 Peer A 和 Peer B 之间建立 WebRTC 连接。

我假设两个对等体之间有一个套接字连接。我们将使用此套接字作为信令服务器。

创建一个全局连接对象,以便我们稍后可以在函数中使用它。

const connection = new RTCPeerConnection();
Enter fullscreen mode Exit fullscreen mode

设置ICE候选监听器

connection.onicecandidate = e => {
   // signalling ICE candidates to Peer B whenever we get it.
   socket.emit("ice-candidate", JSON.stringify(e.candidate));
}
Enter fullscreen mode Exit fullscreen mode

每当我们完成信号传输时,就将冰候选者添加到连接中。

socket.on("ice-candidate", e => {
    connection.addIceCandidate(JSON.parse(e));
});
Enter fullscreen mode Exit fullscreen mode

步骤 1: Peer A为 Peer B创建并发出报价信号。

const makeOffer = async () => {

      // creating offer 
      const offer = await connection.createOffer();
      // setting up offer as Peer's Local Description
      connection.setLocalDescription(offer);
      // signalling offer with Sockets
      socket.emit("offer-created", JSON.stringify({ offer });
}
Enter fullscreen mode Exit fullscreen mode

第二步:同伴 B 接受提议并发出答复信号

const acceptOffer = async (offer) => {
     // setting up offer as Remote Description
     await connection.setRemoteDescription(new RTCSessionDescription(offer));
    // creating answer 
    const answer = await connection.createAnswer();
   // setting up answer as Local Description.
    connection.setLocalDescription(answer);
   // signalling the answer
    socket.emit("answer-added", JSON.stringify({ answer });
}
Enter fullscreen mode Exit fullscreen mode

步骤 3:同伴 A 保存答案

const savingAnswer = async (answer) => {
// lastly, setting up Remote Description of Peer A
    await connection.setRemoteDescription(new RTCSessionDescription(answer));
}
Enter fullscreen mode Exit fullscreen mode

恭喜,您已创建点对点连接。现在双方可以互相交换数据了。

在整个过程中,两个连接彼此共享 ICE 候选。因此,每当我们获得 ICE 候选时,我们都会添加监听器和信令。

在两个对等体之间交换任意数据。

我们可以创建一个连接的数据通道,然后就可以发送和接收数据。

对等体 A 可以创建数据通道。

let DataChannel = Connection.createDataChannel("meeting-chat");
Enter fullscreen mode Exit fullscreen mode

对等体 B 可以监听该数据通道

Connection.ondatachannel = e => {
   DataChannel = e.channel
}
Enter fullscreen mode Exit fullscreen mode

发送和接收消息

// listening for message
DataChannel.onmessage = e => console.log("I got message", e.data);

// sending message
DataChannel.send(JSON.stringify({ message: "Hey Peer" }));
Enter fullscreen mode Exit fullscreen mode

注意:我们需要在对等体开始相互通信之前创建数据通道。否则,双方需要重新协商。

如果对等方需要重新协商,我们可以监听该事件

// this method can be called anytime if Peers need to 
// perform negotiations again.
connection.onnegotiationneeded = e => {
  console.log("Please start the negotiation process again");
}
Enter fullscreen mode Exit fullscreen mode

发送媒体流

const sendStream async () => {
  if(navigator) {
    // browser navigator API to fetch media stream
     const stream = 
   await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
     const newStream = new MediaStream();
     // sending media tracks to peers
     stream.getTracks().forEach((s) => connection.addTrack(s, newStream));
 }
}
Enter fullscreen mode Exit fullscreen mode

接收媒体流

connection.ontrack = e => {
  // you can use this media stream with <video> tag
   console.log("Hey I got Media Streams", e.streams[0]);
}
Enter fullscreen mode Exit fullscreen mode

调试

如果您遇到问题并想要调试您的 WebRTC 连接,您可以在浏览器中进行调试。

brave://webrtc-internals
chrome://webrtc-internals
about:webrtc <!-- For Firefox -->
Enter fullscreen mode Exit fullscreen mode

就是这样。这就是WebRTC 连接的基本实现。如果您想了解更多关于 WebRTC 及其底层工作原理的信息,您需要了解一些网络术语。

网络术语

NAT(网络地址转换)
STUN
TURN(使用中继绕过 NAT)
ICE 候选
SDP(会话描述协议)

我希望这个博客能够帮助您了解如何在下一个项目中使用 WebRTC。

如果你想补充什么,请随时留言。也请在评论区告诉我你最喜欢哪一部分。

谢谢你,
Darshan Ponikar

WebRTC介绍

文章来源:https://dev.to/ponikar/introduction-to-webrtc-3kn8
PREV
可能是你见过的最热门的代码重构🔥
NEXT
TypeScript 简介