12

我正在尝试学习如何创建一个RTCPeerConnection以便我可以使用DataChannelAPI。根据我的理解,这是我尝试过的:

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

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

我在哪里可以了解更多信息?我已经阅读了WebRTC 入门 - HTML5 Rocks教程。

4

3 回答 3

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

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

于 2013-01-03T10:26:03.663 回答
4

发布了一个要点,显示了设置数据连接,与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 Nightly--enable-data-channels才能使其正常工作。

于 2013-02-27T06:41:24.840 回答
4

这是我今天(2014 年 2 月)在 Chrome 中工作的一系列事件。这是一个简化的情况,其中对等方 1 将视频流传输到对等方 2。

  1. 为对等方设置某种方式来交换消息。(可悲的是,人们如何实现这一点的差异使得不同的 WebRTC 代码示例如此不可通约。但在精神上,在您的代码组织中,请尝试将此逻辑与其他逻辑分开。)
  2. 在每一侧,为重要的信令消息设置消息处理程序。您可以设置它们并保留它们。有 3 个核心消息需要处理和发送:
    • 从另一端发送的冰候选人 ==>addIceCandidate与它通话
    • 一个报价消息 ==>SetRemoteDescription用它,然后回答并发送它
    • 回复消息 ===>SetRemoteDescription与它
  3. 在每一侧,创建一个新的 peerconnection 对象并将事件处理程序附加到它以处理重要事件:onicecandidate、onremovestream、onaddstream 等。
    • 冰候选人 ===> 将其发送到另一端
    • 流添加 ===> 将其附加到视频元素,以便您可以看到它
  4. 当两个对等点都存在并且所有处理程序都到位时,对等点 1 会收到某种触发消息以开始视频捕获(使用getUserMedia调用)
  5. 一旦getUserMedia成功,我们就有了一个流。调用addStream对等体 1 的对等连接对象。
  6. 然后 - 并且只有这样 - 对等方 1 提出要约
  7. 由于我们在步骤 2 中设置的处理程序,对等方 2 得到了这个并发送了一个答案
  8. 与此同时(并且有些模糊),对等连接对象开始产生候选冰。它们在两个对等点之间来回发送并处理(上面的步骤 2 和 3)
  9. 由于 2 个条件,流式传输本身不透明地开始:
    • 提供/回答交换
    • 收到、交换和添加的ICE候选人

在第 9 步之后我还没有找到添加视频的方法。当我想更改某些内容时,我会回到第 3 步。

于 2014-02-06T19:07:24.160 回答