How to create data channel in WebRTC peer connection?

后端 未结 3 576
你的背包
你的背包 2021-01-31 06:24

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:

<
相关标签:
3条回答
  • 2021-01-31 06:44

    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.

    1. 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.)
    2. 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
    3. 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
    4. 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)
    5. Once getUserMedia succeeds, we have a stream. Call addStream on the peer 1's peer connection object.
    6. Then -- and only then -- peer 1 makes an offer
    7. Due to the handlers we set up in step 2, peer 2 gets this and sends an answer
    8. 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)
    9. Streaming starts by itself, opaquely, as a result of 2 conditions:
      • offer/answer exchange
      • ice candidates received, exchanged, and added

    I haven't found a way to add video after step 9. When I want to change something, I go back to step 3.

    0 讨论(0)
  • 2021-01-31 06:51

    I finally got it to work after sifting through a lot of articles: 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.

    0 讨论(0)
  • 2021-01-31 06:52

    I've posted a gist that shows setting up a data connection, compatible with both Chrome and 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 before any offers are sent back/forth:

    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:

    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.

    0 讨论(0)
提交回复
热议问题