-
Notifications
You must be signed in to change notification settings - Fork 10
/
datachannels.html
178 lines (145 loc) · 4.42 KB
/
datachannels.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<html>
<head>
<title>DataChannels WebRTC Demo</title>
<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase.js'></script>
</head>
<body>
<textarea id="message"></textarea><button onclick="sendMessage()">Send</button>
<div id="chatlog"></div>
<script>
// get a reference to our FireBase database. You should create your own
// and replace the URL.
var dbRef = new Firebase("https://webrtcdemo.firebaseIO.com/");
var roomRef = dbRef.child("rooms");
// shims!
var PeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var SessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
var IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;
navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
// generate a unique-ish string
function id () {
return (Math.random() * 10000 + 10000 | 0).toString();
}
// a nice wrapper to send data to FireBase
function send (room, key, data) {
roomRef.child(room).child(key).set(data);
}
// wrapper function to receive data from FireBase
function recv (room, type, cb) {
roomRef.child(room).child(type).on("value", function (snapshot, key) {
var data = snapshot.val();
if (data) { cb(data); }
});
}
// generic error handler
function errorHandler (err) {
console.error(err);
}
// determine what type of peer we are,
// offerer or answerer.
var ROOM = location.hash.substr(1);
var type = "answerer";
var otherType = "offerer";
// no room number specified, so create one
// which makes us the offerer
if (!ROOM) {
ROOM = id();
type = "offerer";
otherType = "answerer";
document.write("<a href='#"+ROOM+"'>Send link to other peer</a>");
}
// generate a unique-ish room number
var ME = id();
// get references to the document tags
var chatlog = document.getElementById("chatlog");
var message = document.getElementById("message");
// options for the PeerConnection
var server = {
iceServers: [
{url: "stun:23.21.150.121"},
{url: "stun:stun.l.google.com:19302"},
{url: "turn:numb.viagenie.ca", credential: "webrtcdemo", username: "louis%40mozilla.com"}
]
};
var options = {
optional: [
{DtlsSrtpKeyAgreement: true},
{RtpDataChannels: true} //required for Firefox
]
}
// create the PeerConnection
var pc = new PeerConnection(server, options);
pc.onicecandidate = function (e) {
// take the first candidate that isn't null
if (!e.candidate) { return; }
pc.onicecandidate = null;
// request the other peers ICE candidate
recv(ROOM, "candidate:" + otherType, function (candidate) {
pc.addIceCandidate(new IceCandidate(JSON.parse(candidate)));
});
// send our ICE candidate
send(ROOM, "candidate:"+type, JSON.stringify(e.candidate));
};
// constraints on the offer SDP.
var constraints = {};
// define the channel var
var channel;
connect();
// start the connection!
function connect () {
if (type === "offerer") {
// offerer creates the data channel
channel = pc.createDataChannel("mychannel", {});
// can bind events right away
bindEvents();
// create the offer SDP
pc.createOffer(function (offer) {
pc.setLocalDescription(offer);
// send the offer SDP to FireBase
send(ROOM, "offer", JSON.stringify(offer));
// wait for an answer SDP from FireBase
recv(ROOM, "answer", function (answer) {
pc.setRemoteDescription(
new SessionDescription(JSON.parse(answer))
);
});
}, errorHandler, constraints);
} else {
// answerer must wait for the data channel
pc.ondatachannel = function (e) {
channel = e.channel;
bindEvents(); //now bind the events
};
// answerer needs to wait for an offer before
// generating the answer SDP
recv(ROOM, "offer", function (offer) {
pc.setRemoteDescription(
new SessionDescription(JSON.parse(offer))
);
// now we can generate our answer SDP
pc.createAnswer(function (answer) {
pc.setLocalDescription(answer);
// send it to FireBase
send(ROOM, "answer", JSON.stringify(answer));
}, errorHandler, constraints);
});
}
}
// bind the channel events
function bindEvents () {
channel.onopen = function () { console.log("Channel Open"); }
channel.onmessage = function (e) {
// add the message to the chat log
chatlog.innerHTML += "<div>Peer says: " + e.data + "</div>";
};
}
// send a message the textbox throught
// the data channel for a chat program
function sendMessage () {
var msg = message.value;
channel.send(msg);
message.value = "";
}
</script>
</body>
</html>