javascript - Working Hello World WebRTC DataChannel Examples with Signaling Implemented - Stack Overflow

The intent is for this to bee a Community Wiki post that is kept up-to-date so developers interested in

The intent is for this to bee a Community Wiki post that is kept up-to-date so developers interested in implementing munication of JSON messages browser-to-browser (p2p) with WebRTC DataChannels have simple yet functional examples.

WebRTC DataChannels are experimental and still in draft. It seems that currently the web is a minefield of outdated WebRTC examples and even more so if a developer is trying to learn the RTCDataChannel API.

Simple yet functional 1-page examples that work today across WebRTC pliant browsers seem very difficult to find. For example, some examples leave out a signaling implementation, others only work for a single browser (e.g. Chrome-Chrome), many are outdated due to recent API changes, and others are so plex they create a barrier to getting started.

Please post examples that meet the following criteria (if something is not met please specify):

  1. Client-side code is 1-page (200 lines or less)
  2. Server-side code is 1-page and technology is referenced (e.g. node.js, php, python, etc.)
  3. Signaling mechanism is implemented and protocol technology is referenced (e.g. WebSockets, long polling, GCM, etc.)
  4. Working code that runs cross-browser (Chrome, Firefox, Opera, and/or Bowser)
  5. Minimal options, error handling, abstraction, etc. -- the intent is an elementary example

The intent is for this to bee a Community Wiki post that is kept up-to-date so developers interested in implementing munication of JSON messages browser-to-browser (p2p) with WebRTC DataChannels have simple yet functional examples.

WebRTC DataChannels are experimental and still in draft. It seems that currently the web is a minefield of outdated WebRTC examples and even more so if a developer is trying to learn the RTCDataChannel API.

Simple yet functional 1-page examples that work today across WebRTC pliant browsers seem very difficult to find. For example, some examples leave out a signaling implementation, others only work for a single browser (e.g. Chrome-Chrome), many are outdated due to recent API changes, and others are so plex they create a barrier to getting started.

Please post examples that meet the following criteria (if something is not met please specify):

  1. Client-side code is 1-page (200 lines or less)
  2. Server-side code is 1-page and technology is referenced (e.g. node.js, php, python, etc.)
  3. Signaling mechanism is implemented and protocol technology is referenced (e.g. WebSockets, long polling, GCM, etc.)
  4. Working code that runs cross-browser (Chrome, Firefox, Opera, and/or Bowser)
  5. Minimal options, error handling, abstraction, etc. -- the intent is an elementary example
Share Improve this question edited May 23, 2017 at 12:02 CommunityBot 11 silver badge asked Aug 23, 2015 at 23:39 LightbeardLightbeard 4,13110 gold badges51 silver badges60 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

Here is a working example that uses HTML5 WebSockets for signaling and a node.js backend

signaling technology: WebSockets
client: pure html/javascript
server: node.js, ws
last tested on: Firefox 40.0.2, Chrome 44.0.2403.157 m, Opera 31.0.1889.174


client-side code:

<html>
<head>
</head>
<body>
    <p id='msg'>Click the following in different browser windows</p>
    <button type='button' onclick='init(false)'>I AM Answerer Peer (click first)</button>
    <button type='button' onclick='init(true)'>I AM Offerer Peer</button>

<script>
    (function() {   
        var offererId = 'Gandalf',   // note: client id conflicts can happen
            answererId = 'Saruman',  //       no websocket cleanup code exists
            ourId, peerId,
            RTC_IS_MOZILLA = !!window.mozRTCPeerConnection,
            RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection || window.msRTCPeerConnection,
            RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.msRTCSessionDescription,
            RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.msRTCIceCandidate,
            rtcpeerconn = new RTCPeerConnection(
                    {iceServers: [{ 'url': 'stun:stun.services.mozilla.'}, {'url': 'stun:stun.l.google.:19302'}]}, 
                    {optional: [{RtpDataChannels: false}]}
                ),
            rtcdatachannel, 
            websocket = new WebSocket('ws://' + window.location.hostname + ':8000'),
            ready, onerror;

        window.init = function(weAreOfferer) {
            ourId = weAreOfferer ? offererId : answererId;
            peerId = weAreOfferer ? answererId : offererId;

            websocket.send(JSON.stringify({
                inst: 'init', 
                id: ourId
            }));

            if(weAreOfferer) {

                rtcdatachannel = rtcpeerconn.createDataChannel(offererId+answererId);
                rtcdatachannel.onopen = ready;
                rtcdatachannel.onerror = onerror;

                rtcpeerconn.createOffer(function(offer) {
                    rtcpeerconn.setLocalDescription(offer, function() {
                        var output = offer.toJSON();
                        if(typeof output === 'string') output = JSON.parse(output); // normalize: RTCSessionDescription.toJSON returns a json str in FF, but json obj in Chrome

                        websocket.send(JSON.stringify({
                            inst: 'send', 
                            peerId: peerId, 
                            message: output
                        }));
                    }, onerror);
                }, onerror);
            }
        };

        rtcpeerconn.ondatachannel = function(event) {
            rtcdatachannel = event.channel;
            rtcdatachannel.onopen = ready;
            rtcdatachannel.onerror = onerror;
        };

        websocket.onmessage = function(input) {
            var message = JSON.parse(input.data);

            if(message.type && message.type === 'offer') {
                var offer = new RTCSessionDescription(message);

                rtcpeerconn.setRemoteDescription(offer, function() {
                    rtcpeerconn.createAnswer(function(answer) {
                        rtcpeerconn.setLocalDescription(answer, function() {
                            var output = answer.toJSON();
                            if(typeof output === 'string') output = JSON.parse(output); // normalize: RTCSessionDescription.toJSON returns a json str in FF, but json obj in Chrome

                            websocket.send(JSON.stringify({
                                inst: 'send',
                                peerId: peerId,
                                message: output
                            }));
                        }, onerror);
                    }, onerror);                
                }, onerror);
            } else if(message.type && message.type === 'answer') {              
                var answer = new RTCSessionDescription(message);
                rtcpeerconn.setRemoteDescription(answer, function() {/* handler required but we have nothing to do */}, onerror);
            } else if(rtcpeerconn.remoteDescription) {
                // ignore ice candidates until remote description is set
                rtcpeerconn.addIceCandidate(new RTCIceCandidate(message.candidate));
            }
        };

        rtcpeerconn.onicecandidate = function (event) {
            if (!event || !event.candidate) return;
            websocket.send(JSON.stringify({
                inst: 'send',
                peerId: peerId,
                message: {candidate: event.candidate}
            }));
        };

        /** called when RTC signaling is plete and RTCDataChannel is ready */
        ready = function() {
            rtcdatachannel.send('hello world!');
            rtcdatachannel.onmessage = function(event) {
                document.getElementById('msg').innerHTML = 'RTCDataChannel peer ' + peerId + ' says: ' + event.data;    
            }
        };

        /** global error function */
        onerror = websocket.onerror = function(e) {
            console.log('====== WEBRTC ERROR ======', arguments);
            document.getElementById('msg').innerHTML = '====== WEBRTC ERROR ======<br>' + e;
            throw new Error(e);
        };
    })();
</script>
</body>
</html>

server-side code:

var server = require('http').createServer(), 
    express = require('express'),    
    app = express(),
    WebSocketServer = require('ws').Server,
    wss = new WebSocketServer({ server: server, port: 8000 });

app.use(express.static(__dirname + '/static')); // client code goes in static directory

var clientMap = {};

wss.on('connection', function (ws) {
    ws.on('message', function (inputStr) {
        var input = JSON.parse(inputStr);
        if(input.inst == 'init') {
            clientMap[input.id] = ws;
        } else if(input.inst == 'send') {
            clientMap[input.peerId].send(JSON.stringify(input.message));
        }
    });
});

server.on('request', app);
server.listen(80, YOUR_HOSTNAME_OR_IP_HERE, function () { console.log('Listening on ' + server.address().port) });

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744592691a4582702.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信