如何在WebRTC对等连接中创建数据通道?

时间:2013-01-03 06:31:28

标签: javascript webrtc

我正在尝试学习如何创建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);
        }
    });
});

我不确定出了什么问题,但我假设连接永远不会建立,因为没有显示任何消息。

我在哪里可以了解更多相关信息?我已经阅读了Getting Started with WebRTC - HTML5 Rocks教程。

3 个答案:

答案 0 :(得分:13)

我在筛选了很多文章后终于开始工作了:http://jsfiddle.net/LcQzV/

首先我们创建对等连接:

var media = {};
media.fake = media.audio = true;
var client = new mozRTCPeerConnection;
var server = new mozRTCPeerConnection;

当客户端连接到服务器时,它必须打开一个数据通道:

client.onconnection = function () {
    var channel = client.createDataChannel("chat", {});

    channel.onmessage = function (event) {
        alert("Server: " + event.data);
    };

    channel.onopen = function () {
        channel.send("Hello Server!");
    };
};

当客户端创建数据通道时,服务器可能会响应:

server.ondatachannel = function (channel) {
    channel.onmessage = function (event) {
        alert("Client: " + event.data);
    };

    channel.onopen = function () {
        channel.send("Hello Client!");
    };
};

我们需要向客户端和服务器添加假音频流以建立连接:

navigator.mozGetUserMedia(media, callback, errback);

function callback(fakeAudio) {
    server.addStream(fakeAudio);
    client.addStream(fakeAudio);
    client.createOffer(offer);
}

function errback(error) {
    alert(error);
}

客户创建优惠:

function offer(description) {
    client.setLocalDescription(description, function () {
        server.setRemoteDescription(description, function () {
            server.createAnswer(answer);
        });
    });
}

服务器接受要约并建立连接:

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);
        });
    });
}

呼。这需要一段时间才能理解。

答案 1 :(得分:4)

posted a gist显示设置数据连接,与兼容 Chrome和Firefox兼容。

主要区别在于,在FF中你需要等到设置连接,在Chrome中它恰恰相反:在发送任何优惠之前,您似乎需要创建数据连接前/后:

var pc1 = new RTCPeerConnection(cfg, con);
if (!pc1.connectDataConnection) setupDC1();    // Chrome...Firefox defers per other answer

另一个区别是Chrome将事件对象传递给.ondatachannel,而FF只传递原始频道:

pc2.ondatachannel = function (e) {
    var datachannel = e.channel || e;

请注意,您目前需要Chrome {每晚启动--enable-data-channels才能使用它。

答案 2 :(得分:4)

以下是我今天(2014年2月)在Chrome中发布的一系列事件。这是针对简化的情况,其中对等体1将视频流式传输到对等体2。

  1. 为对等方设置一些交换消息的方法。 (人们如何实现这一点的不同之处在于,不同的WebRTC代码示例如此难以理解,令人遗憾。但在精神上,在您的代码组织中,尝试将此逻辑与其他代码分开。)
  2. 在每一侧,为重要的信令消息设置消息处理程序。你可以设置它们并将它们保留下来。有三个核心消息要处理&发送:
    • 从另一方发送的冰候选人==>用它来呼叫addIceCandidate
    • 优惠讯息==> SetRemoteDescription用它,然后回答&发送它
    • 回答消息===> SetRemoteDescription随身携带
  3. 在每一侧,创建一个新的peerconnection对象,并为其执行重要事件的事件处理程序:onicecandidate,onremovestream,onaddstream等。
    • 冰候选人===>将其发送到另一方
    • stream added ===>将它附加到视频元素,以便您可以看到它
  4. 当两个对等方都存在并且所有处理程序都已到位时,对等方1会获得某种触发消息以启动视频捕获(使用getUserMedia调用)
  5. 一旦getUserMedia成功,我们就有了一个流。在对等方1的对等连接对象上调用addStream
  6. 然后 - 只有那时 - 同伴1提出要约
  7. 由于我们在步骤2中设置了处理程序,因此对等方2获取此处并发送答案
  8. 与此同时(并且有点模糊),对等连接对象开始产生冰候选者。它们在两个同伴之间来回传递并处理(上面的步骤2和3)
  9. 由于两个条件,流式传输本身是不透明的:
    • 提供/回答交流
    • 冰候选人收到,交换和添加
  10. 我还没有找到在第9步之后添加视频的方法。当我想要改变某些内容时,我会回到第3步。