1<html>
2<head>
3<title>PeerConnection server test page</title>
4
5<script>
6var request = null;
7var hangingGet = null;
8var localName;
9var server;
10var my_id = -1;
11var other_peers = {};
12var message_counter = 0;
13
14function trace(txt) {
15  var elem = document.getElementById("debug");
16  elem.innerHTML += txt + "<br>";
17}
18
19function handleServerNotification(data) {
20  trace("Server notification: " + data);
21  var parsed = data.split(',');
22  if (parseInt(parsed[2]) != 0)
23    other_peers[parseInt(parsed[1])] = parsed[0];
24}
25
26function handlePeerMessage(peer_id, data) {
27  ++message_counter;
28  var str = "Message from '" + other_peers[peer_id] + "'&nbsp;";
29  str += "<span id='toggle_" + message_counter + "' onclick='toggleMe(this);' ";
30  str += "style='cursor: pointer'>+</span><br>";
31  str += "<blockquote id='msg_" + message_counter + "' style='display:none'>";
32  str += data + "</blockquote>";
33  trace(str);
34  if (document.getElementById("loopback").checked) {
35    if (data.search("offer") != -1) {
36      // In loopback mode, if DTLS is enabled, notify the client to disable it.
37      // Otherwise replace the offer with an answer.
38      if (data.search("fingerprint") != -1)
39        data = data.replace("offer", "offer-loopback");
40      else
41        data = data.replace("offer", "answer");
42    }
43    sendToPeer(peer_id, data);
44  }
45}
46
47function GetIntHeader(r, name) {
48  var val = r.getResponseHeader(name);
49  return val != null && val.length ? parseInt(val) : -1;
50}
51
52function hangingGetCallback() {
53  try {
54    if (hangingGet.readyState != 4)
55      return;
56    if (hangingGet.status != 200) {
57      trace("server error: " + hangingGet.statusText);
58      disconnect();
59    } else {
60      var peer_id = GetIntHeader(hangingGet, "Pragma");
61      if (peer_id == my_id) {
62        handleServerNotification(hangingGet.responseText);
63      } else {
64        handlePeerMessage(peer_id, hangingGet.responseText);
65      }
66    }
67
68    if (hangingGet) {
69      hangingGet.abort();
70      hangingGet = null;
71    }
72
73    if (my_id != -1)
74      window.setTimeout(startHangingGet, 0);
75  } catch (e) {
76    trace("Hanging get error: " + e.description);
77  }
78}
79
80function startHangingGet() {
81  try {
82    hangingGet = new XMLHttpRequest();
83    hangingGet.onreadystatechange = hangingGetCallback;
84    hangingGet.ontimeout = onHangingGetTimeout;
85    hangingGet.open("GET", server + "/wait?peer_id=" + my_id, true);
86    hangingGet.send();
87  } catch (e) {
88    trace("error" + e.description);
89  }
90}
91
92function onHangingGetTimeout() {
93  trace("hanging get timeout. issuing again.");
94  hangingGet.abort();
95  hangingGet = null;
96  if (my_id != -1)
97    window.setTimeout(startHangingGet, 0);
98}
99
100function signInCallback() {
101  try {
102    if (request.readyState == 4) {
103      if (request.status == 200) {
104        var peers = request.responseText.split("\n");
105        my_id = parseInt(peers[0].split(',')[1]);
106        trace("My id: " + my_id);
107        for (var i = 1; i < peers.length; ++i) {
108          if (peers[i].length > 0) {
109            trace("Peer " + i + ": " + peers[i]);
110            var parsed = peers[i].split(',');
111            other_peers[parseInt(parsed[1])] = parsed[0];
112          }
113        }
114        startHangingGet();
115        request = null;
116      }
117    }
118  } catch (e) {
119    trace("error: " + e.description);
120  }
121}
122
123function signIn() {
124  try {
125    request = new XMLHttpRequest();
126    request.onreadystatechange = signInCallback;
127    request.open("GET", server + "/sign_in?" + localName, true);
128    request.send();
129  } catch (e) {
130    trace("error: " + e.description);
131  }
132}
133
134function sendToPeer(peer_id, data) {
135  if (my_id == -1) {
136    alert("Not connected");
137    return;
138  }
139  if (peer_id == my_id) {
140    alert("Can't send a message to oneself :)");
141    return;
142  }
143  var r = new XMLHttpRequest();
144  r.open("POST", server + "/message?peer_id=" + my_id + "&to=" + peer_id,
145         false);
146  r.setRequestHeader("Content-Type", "text/plain");
147  r.send(data);
148  r = null;
149}
150
151function connect() {
152  localName = document.getElementById("local").value.toLowerCase();
153  server = document.getElementById("server").value.toLowerCase();
154  if (localName.length == 0) {
155    alert("I need a name please.");
156    document.getElementById("local").focus();
157  } else {
158    document.getElementById("connect").disabled = true;
159    document.getElementById("disconnect").disabled = false;
160    document.getElementById("send").disabled = false;
161    signIn();
162  }
163}
164
165function disconnect() {
166  if (request) {
167    request.abort();
168    request = null;
169  }
170
171  if (hangingGet) {
172    hangingGet.abort();
173    hangingGet = null;
174  }
175
176  if (my_id != -1) {
177    request = new XMLHttpRequest();
178    request.open("GET", server + "/sign_out?peer_id=" + my_id, false);
179    request.send();
180    request = null;
181    my_id = -1;
182  }
183
184  document.getElementById("connect").disabled = false;
185  document.getElementById("disconnect").disabled = true;
186  document.getElementById("send").disabled = true;
187}
188
189window.onbeforeunload = disconnect;
190
191function send() {
192  var text = document.getElementById("message").value;
193  var peer_id = parseInt(document.getElementById("peer_id").value);
194  if (!text.length || peer_id == 0) {
195    alert("No text supplied or invalid peer id");
196  } else {
197    sendToPeer(peer_id, text);
198  }
199}
200
201function toggleMe(obj) {
202  var id = obj.id.replace("toggle", "msg");
203  var t = document.getElementById(id);
204  if (obj.innerText == "+") {
205    obj.innerText = "-";
206    t.style.display = "block";
207  } else {
208    obj.innerText = "+";
209    t.style.display = "none";
210  }
211}
212
213</script>
214
215</head>
216<body>
217Server: <input type="text" id="server" value="http://localhost:8888" /><br>
218<input type="checkbox" id="loopback" checked="checked"/> Loopback (just send
219received messages right back)<br>
220Your name: <input type="text" id="local" value="my_name"/>
221<button id="connect" onclick="connect();">Connect</button>
222<button disabled="true" id="disconnect"
223        onclick="disconnect();">Disconnect</button>
224<br>
225<table><tr><td>
226Target peer id: <input type="text" id="peer_id" size="3"/></td><td>
227Message: <input type="text" id="message"/></td><td>
228<button disabled="true" id="send" onclick="send();">Send</button>
229</td></tr></table>
230<button onclick="document.getElementById('debug').innerHTML='';">
231Clear log</button>
232
233<pre id="debug">
234</pre>
235<br><hr>
236</body>
237</html>
238