首页>>新闻资讯>>云计算

WebRTC对等连接- 连接不同设备上的浏览器

2024-10-09 09:22:11 5

WebRTC对等通信-在不同设备上连接浏览器

我们成功了!不需要服务器即可使不同设备上的两个浏览器相互交流,只需要在开始交互的时候使用服务器。

点击此处运行代码,在不同的设备上打开两个链接。

如何使用WebRTC连接不同设备上的浏览器

你可以使用WebRTC在无服务器时使浏览器相互交流,但是由于没有服务发现,我们需要一个发信服务器来使浏览器可以找到彼此。

步骤如下:

1.客户端1 对服务器说hi并注册。

2.客户端2 对服务器说hi并注册。

3.服务器记录身份信息(用户名)

4.客户端1命令服务器呼叫客户端2

5.服务器告诉客户端2有呼叫信息。

6.客户端2接收呼叫。

7.客户端1和2直接交流。

我们模仿MDN的WebRTC交流实例来形成代码框架。

WebSocket信令服务器

发信号是两个浏览器之间的交互过程,我们使用了WebSockets来完成。

服务器部分和MDN的例子相同,只需复制。

我们做出了一些改变使它可以对now.sh项目工作。名称上,我们移除了所有SSL部分。Zeit将我们的服务器包进一个安全的SSL 服务器,SSL服务器接着通过一个非加密连接与实际服务器进行交流。

如果没有SSL,WebSockets不能在现代浏览器中起作用。如果没有运行本地主机,它对自签名证书不工作。如果需要两个不在本地设备上的浏览器交流,必须确保一个SSL证书。

最简单的方法是在now项目上进行。

连接信令服务器

通过40行helper类的WebSockets可以与服务器交流。实例化类,建立连接,收听信息。

我们在connetToSocket中建立了一个new WebSocket,加入一些反馈,期待好的效果。Onmessage允许我们之后通过messageListeners数组添加额外的message listeners 窗口。

SendToServer 允许向服务器发送JSON对象,并且addMsgListener允许添加一个新的message listener 窗口。 我们使用它来连接PeerConnection 和服务器。

建立PeerConnection接口

从WebRTC part1 可以学到, 我们把RTCPeerConnection组件分成了help class。

以下148行代码完成了整个周期。我们之前讨论过此代码,这是重述。

Constructor建立了一些实例变量,一个新的RTCPeerConnection对象,告诉它用哪个iceServers,连接本地event listeners,然后开始接受信令服务器信息,并添加媒体流到peerConnection.

下一步是处理ICECandidate,当有新连接时它将建立一个的交互连接。它会ping信令服务器,告诉信令服务器,这里有新的ICE candidate.

handleICECandidateEvent = event => { if (event.candidate) { this.signalingConnection.sendToServer({ type: "new-ice-candidate", target: this.targetUsername, candidate: event.candidate }); } };

这之后,我们得到了

handleNegotiationNeededEvent,当RTCPeerConnection需要新连接时,它会被调用。(我也不知道是什么触发了它)

但是函数产生了一个新的连接请求,更新了本地SDP描述,并且告知信令服务器它在尝试连接。

handleNegotiationNeededEvent = () => { const { username, targetUsername } = this; this.peerConnection .createOffer() .then(offer => this.peerConnection.setLocalDescription(offer)) .then(() => this.signalingConnection.sendToServer({ name: username, target: targetUsername, type: "video-offer", sdp: this.peerConnection.localDescription }) ) .catch(console.error); };

处理信令消息

接着到了有趣的部分,处理信令服务器的消息。

onSignalingMessage = (msg) => { switch (msg.type) { case "video-answer": // Callee has answered our offer this.videoAnswer(msg); break; case "new-ice-candidate": // A new ICE candidate has been received this.newICECandidate(msg) break; case "hang-up": // The other peer has hung up the call this.close() break; } }

当接收新信息时,我们可以做许多事。把我们自己设置成接收方,向连接中添加新的candidate或关闭。

videoAnswer = ({ sdp }) => { this.peerConnection .setRemoteDescription(new RTCSessionDescription(sdp)) .catch(console.error); } newICECandidate = ({ candidate }) => { this.peerConnection.addIceCandidate(new RTCIceCandidate(candidate)); } close = () => { this.peerConnection.close(); this.peerConnection = null; this.onClose() }

这就是我们的PeerConnection对象。理论上,我们可以实例化许多PeerConnection对象来同时连接远端机器。

这将会是一个有趣的尝试。

将所有部件整合

把这些组合起来的,就是我们的

WebRTCPeerConnectionWithServer反应组件,经过用户界面,实例化helper类,处理用户点击按钮的过程。

点击此处查看GitHub完整文件。

以下是其中比较重要的部分:

call = user => { this.setState({ targetUsername: user }); this.createPeerConnection(); }; hangUp = () => { this.signalingConnection.sendToServer({ name: this.state.username, target: this.state.targetUsername, type: "hang-up" }); this.peerConnection.close(); }; createPeerConnection = () => { if (this.peerConnection) return; this.peerConnection = new PeerConnection({ gotRemoteStream: this.gotRemoteStream, gotRemoteTrack: this.gotRemoteTrack, signalingConnection: this.signalingConnection, onClose: this.closeVideoCall, localStream: this.state.localStream, username: this.state.username, targetUsername: this.state.targetUsername }); }; closeVideoCall = () => { this.remoteVideoRef.current.srcObject && this.remoteVideoRef.current.srcObject .getTracks() .forEach(track => track.stop()); this.remoteVideoRef.current.src = null; this.setState({ targetUsername: null, callDisabled: false }); };

函数从call开始启动,保存我们正在调用的状态,建立一个新的peer连接。

CreatePeerConnection把所有信息传入PeerConnection类。

HangUp和closeVideoCall共同工作来停止调用。我们需要两者因为其中一个是用户控制的,而当挂断命令从另一边传来的时候,另一个被调用。

最后一步

在粘合区有一条信令服务器发出的信息需要我们处理: 调用请求。

case "video-offer": // Invitation and offer to chat this.createPeerConnection(); this.peerConnection.videoOffer(msg); break;

当服务器告知需要连接时,我们需要在客户端创建一个新的PeerConnection对象,并处理请求。处理请求意味着设置一个远程SDP描述并发送应答。

videoOffer = ({ sdp }) => { const { username, targetUsername } = this; this.peerConnection .setRemoteDescription(new RTCSessionDescription(sdp)) .then(() => this.peerConnection.createAnswer()) .then(answer => { return this.peerConnection.setLocalDescription(answer); }) .then(() => { this.signalingConnection.sendToServer({ name: username, targetUsername: targetUsername, type: "video-answer", sdp: this.peerConnection.localDescription }); }) .catch(console.error); }

成功工作

将所有部分结合,现在你可以在不同设备的两个浏览器上相互交流而不再需要服务器。

相关标签:

发表评论:

评论记录:

未查询到任何数据!