javascript 如何在 WebRTC 对等连接中创建数据通道?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14134090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create data channel in WebRTC peer connection?
提问by Aadit M Shah
I'm trying to learn how to create an RTCPeerConnection
so that I can use the DataChannel
API. Here's what I have tried from what I understood:
我正在尝试学习如何创建一个RTCPeerConnection
以便我可以使用DataChannel
API。根据我的理解,这是我尝试过的:
var client = new mozRTCPeerConnection;
var server = new mozRTCPeerConnection;
client.createOffer(function (description) {
client.setLocalDescription(description);
server.setRemoteDescription(description);
server.createAnswer(function (description) {
server.setLocalDescription(description);
client.setRemoteDescription(description);
var clientChannel = client.createDataChannel("chat");
var serverChannel = server.createDataChannel("chat");
clientChannel.onmessage = serverChannel.onmessage = onmessage;
clientChannel.send("Hello Server!");
serverChannel.send("Hello Client!");
function onmessage(event) {
alert(event.data);
}
});
});
I'm not sure what's going wrong, but I'm assuming that the connection is never established because no messages are being displayed.
我不确定出了什么问题,但我假设连接从未建立,因为没有显示任何消息。
Where do I learn more about this? I've already read the Getting Started with WebRTC - HTML5 Rockstutorial.
我在哪里可以了解更多相关信息?我已经阅读了WebRTC 入门 - HTML5 Rocks教程。
回答by Aadit M Shah
I finally got it to work after sifting through a lot of articles: http://jsfiddle.net/LcQzV/
在筛选了很多文章后,我终于让它工作了:http: //jsfiddle.net/LcQzV/
First we create the peer connections:
首先我们创建对等连接:
var media = {};
media.fake = media.audio = true;
var client = new mozRTCPeerConnection;
var server = new mozRTCPeerConnection;
When the client connects to the server it must open a data channel:
当客户端连接到服务器时,它必须打开一个数据通道:
client.onconnection = function () {
var channel = client.createDataChannel("chat", {});
channel.onmessage = function (event) {
alert("Server: " + event.data);
};
channel.onopen = function () {
channel.send("Hello Server!");
};
};
When the client creates a data channel the server may respond:
当客户端创建数据通道时,服务器可能会响应:
server.ondatachannel = function (channel) {
channel.onmessage = function (event) {
alert("Client: " + event.data);
};
channel.onopen = function () {
channel.send("Hello Client!");
};
};
We need to add a fake audio stream to the client and the server to establish a connection:
我们需要向客户端和服务器添加一个假音频流来建立连接:
navigator.mozGetUserMedia(media, callback, errback);
function callback(fakeAudio) {
server.addStream(fakeAudio);
client.addStream(fakeAudio);
client.createOffer(offer);
}
function errback(error) {
alert(error);
}
The client creates an offer:
客户创建报价:
function offer(description) {
client.setLocalDescription(description, function () {
server.setRemoteDescription(description, function () {
server.createAnswer(answer);
});
});
}
The server accepts the offer and establishes a connection:
服务器接受报价并建立连接:
function answer(description) {
server.setLocalDescription(description, function () {
client.setRemoteDescription(description, function () {
var port1 = Date.now();
var port2 = port1 + 1;
client.connectDataConnection(port1, port2);
server.connectDataConnection(port2, port1);
});
});
}
Phew. That took a while to understand.
呼。这花了一段时间才明白。
回答by natevw
I've posted a gistthat shows setting up a data connection, compatible with bothChrome and Firefox.
我已经发布了一个要点昭示着建立数据连接,兼容两种Chrome和Firefox。
The main difference is that where in FF you have to wait until the connection is set up, in Chrome it's just the opposite: it seems you need to create the data connection beforeany offers are sent back/forth:
主要区别在于,在 FF 中,您必须等到连接建立,而在 Chrome 中,情况正好相反:似乎您需要在来回发送任何报价之前创建数据连接:
var pc1 = new RTCPeerConnection(cfg, con);
if (!pc1.connectDataConnection) setupDC1(); // Chrome...Firefox defers per other answer
The other difference is that Chrome passes an event object to .ondatachannel
whereas FF passes just a raw channel:
另一个区别是 Chrome 传递一个事件对象,.ondatachannel
而 FF 只传递一个原始通道:
pc2.ondatachannel = function (e) {
var datachannel = e.channel || e;
Note that you currently need Chrome Nightly started with --enable-data-channels
for it to work as well.
请注意,您目前需要 Chrome Nightly 启动--enable-data-channels
才能正常工作。
回答by sandover
Here is a sequence of events I have working today (Feb 2014) in Chrome. This is for a simplified case where peer 1 will stream video to peer 2.
这是我今天(2014 年 2 月)在 Chrome 中处理的一系列事件。这是对等端 1 将视频流式传输到对端 2 的简化情况。
- Set up some way for the peers to exchange messages. (The variance in how people accomplish this is what makes different WebRTC code samples so incommensurable, sadly. But mentally, and in your code organization, try to separate this logic out from the rest.)
- On each side, set up message handlers for the important signalling messages. You can set them up and leave them up. There are 3 core messages to handle & send:
- an ice candidate sent from the other side ==> call
addIceCandidate
with it - an offer message ==>
SetRemoteDescription
with it, then make an answer & send it - an answer message ===>
SetRemoteDescription
with it
- an ice candidate sent from the other side ==> call
- On each side, create a new peerconnection object and attach event handlers to it for important events: onicecandidate, onremovestream, onaddstream, etc.
- ice candidate ===> send it to other side
- stream added ===> attach it to a video element so you can see it
- When both peers are present and all the handlers are in place, peer 1 gets a trigger message of some kind to start video capture (using the
getUserMedia
call) - Once
getUserMedia
succeeds, we have a stream. CalladdStream
on the peer 1's peer connection object. - Then -- and only then -- peer 1 makes an offer
- Due to the handlers we set up in step 2, peer 2 gets this and sends an answer
- Concurrently with this (and somewhat obscurely), the peer connection object starts producing ice candidates. They get sent back and forth between the two peers and handled (steps 2 & 3 above)
- Streaming starts by itself, opaquely, as a result of 2 conditions:
- offer/answer exchange
- ice candidates received, exchanged, and added
- 为对等方设置某种方式来交换消息。(令人遗憾的是,人们如何实现这一点的差异导致不同的 WebRTC 代码示例如此不可通约。但在精神上,在您的代码组织中,请尝试将此逻辑与其他逻辑区分开来。)
- 在每一侧,为重要的信令消息设置消息处理程序。您可以设置它们并保留它们。有 3 个核心消息需要处理和发送:
- 从另一方发送的冰候选人 ==>
addIceCandidate
用它调用 - 提供信息 ==>
SetRemoteDescription
用它,然后回答并发送 - 一条回复消息 ===>
SetRemoteDescription
与它
- 从另一方发送的冰候选人 ==>
- 在每一侧,创建一个新的 peerconnection 对象,并为重要事件附加事件处理程序:onicecandidate、onremovestream、onaddstream 等。
- 冰候选人 ===> 将其发送给另一方
- 流添加 ===> 将其附加到视频元素,以便您可以看到它
- 当两个对等点都存在并且所有处理程序都到位时,对等点 1 会收到某种触发消息以开始视频捕获(使用
getUserMedia
调用) - 一旦
getUserMedia
成功,我们就有了一个流。调用addStream
peer 1 的 peer 连接对象。 - 然后——而且只有这样——peer 1 提出要约
- 由于我们在步骤 2 中设置的处理程序,对等方 2 得到这个并发送一个答案
- 与此同时(并且有些晦涩),对等连接对象开始生成冰候选。它们在两个对等点之间来回发送并处理(上面的第 2 步和第 3 步)
- 由于 2 个条件,流式传输本身不透明地开始:
- 提供/答复交换
- 接收、交换和添加冰候选
I haven't found a way to add video after step 9. When I want to change something, I go back to step 3.
在第9步之后我还没有找到添加视频的方法。当我想改变一些东西时,我回到第3步。