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, replace the offer with an answer.
37      data = data.replace("offer", "answer");
38      // Keep only the first crypto line for each m line in the answer.
39      var mlines = data.split("m=");
40      // Start from 1 because the first item in the array is not a m line.
41      for (var i = 1; i < mlines.length; ++i) {
42        var mline = mlines[i];
43        var cryptoBegin = mline.indexOf("a=crypto:", 0);
44        if (cryptoBegin == -1) {
45          // No crypto line found.
46          continue;
47        }
48        // Skip the first crypto line.
49        cryptoBegin = mline.indexOf("a=crypto:", cryptoBegin + 1);
50        while (cryptoBegin != -1) {
51          var cryptoEnd = mline.indexOf("\\n", cryptoBegin);
52          var crypto = mline.substring(cryptoBegin, cryptoEnd + 2);
53          data = data.replace(crypto, "");
54          // Search for the the next crypto line.
55          cryptoBegin = mline.indexOf("a=crypto:", cryptoBegin + 1);
56        }
57      }
58    }
59    sendToPeer(peer_id, data);
60  }
61}
62
63function GetIntHeader(r, name) {
64  var val = r.getResponseHeader(name);
65  return val != null && val.length ? parseInt(val) : -1;
66}
67
68function hangingGetCallback() {
69  try {
70    if (hangingGet.readyState != 4)
71      return;
72    if (hangingGet.status != 200) {
73      trace("server error: " + hangingGet.statusText);
74      disconnect();
75    } else {
76      var peer_id = GetIntHeader(hangingGet, "Pragma");
77      if (peer_id == my_id) {
78        handleServerNotification(hangingGet.responseText);
79      } else {
80        handlePeerMessage(peer_id, hangingGet.responseText);
81      }
82    }
83
84    if (hangingGet) {
85      hangingGet.abort();
86      hangingGet = null;
87    }
88
89    if (my_id != -1)
90      window.setTimeout(startHangingGet, 0);
91  } catch (e) {
92    trace("Hanging get error: " + e.description);
93  }
94}
95
96function startHangingGet() {
97  try {
98    hangingGet = new XMLHttpRequest();
99    hangingGet.onreadystatechange = hangingGetCallback;
100    hangingGet.ontimeout = onHangingGetTimeout;
101    hangingGet.open("GET", server + "/wait?peer_id=" + my_id, true);
102    hangingGet.send();  
103  } catch (e) {
104    trace("error" + e.description);
105  }
106}
107
108function onHangingGetTimeout() {
109  trace("hanging get timeout. issuing again.");
110  hangingGet.abort();
111  hangingGet = null;
112  if (my_id != -1)
113    window.setTimeout(startHangingGet, 0);
114}
115
116function signInCallback() {
117  try {
118    if (request.readyState == 4) {
119      if (request.status == 200) {
120        var peers = request.responseText.split("\n");
121        my_id = parseInt(peers[0].split(',')[1]);
122        trace("My id: " + my_id);
123        for (var i = 1; i < peers.length; ++i) {
124          if (peers[i].length > 0) {
125            trace("Peer " + i + ": " + peers[i]);
126            var parsed = peers[i].split(',');
127            other_peers[parseInt(parsed[1])] = parsed[0];
128          }
129        }
130        startHangingGet();
131        request = null;
132      }
133    }
134  } catch (e) {
135    trace("error: " + e.description);
136  }
137}
138
139function signIn() {
140  try {
141    request = new XMLHttpRequest();
142    request.onreadystatechange = signInCallback;
143    request.open("GET", server + "/sign_in?" + localName, true);
144    request.send();
145  } catch (e) {
146    trace("error: " + e.description);
147  }
148}
149
150function sendToPeer(peer_id, data) {
151  if (my_id == -1) {
152    alert("Not connected");
153    return;
154  }
155  if (peer_id == my_id) {
156    alert("Can't send a message to oneself :)");
157    return;
158  }
159  var r = new XMLHttpRequest();
160  r.open("POST", server + "/message?peer_id=" + my_id + "&to=" + peer_id,
161         false);
162  r.setRequestHeader("Content-Type", "text/plain");
163  r.send(data);
164  r = null;
165}
166
167function connect() {
168  localName = document.getElementById("local").value.toLowerCase();
169  server = document.getElementById("server").value.toLowerCase();
170  if (localName.length == 0) {
171    alert("I need a name please.");
172    document.getElementById("local").focus();
173  } else {
174    document.getElementById("connect").disabled = true;
175    document.getElementById("disconnect").disabled = false;
176    document.getElementById("send").disabled = false;
177    signIn();
178  }
179}
180
181function disconnect() {
182  if (request) {
183    request.abort();
184    request = null;
185  }
186  
187  if (hangingGet) {
188    hangingGet.abort();
189    hangingGet = null;
190  }
191
192  if (my_id != -1) {
193    request = new XMLHttpRequest();
194    request.open("GET", server + "/sign_out?peer_id=" + my_id, false);
195    request.send();
196    request = null;
197    my_id = -1;
198  }
199
200  document.getElementById("connect").disabled = false;
201  document.getElementById("disconnect").disabled = true;
202  document.getElementById("send").disabled = true;
203}
204
205window.onbeforeunload = disconnect;
206
207function send() {
208  var text = document.getElementById("message").value;
209  var peer_id = parseInt(document.getElementById("peer_id").value);
210  if (!text.length || peer_id == 0) {
211    alert("No text supplied or invalid peer id");
212  } else {
213    sendToPeer(peer_id, text);
214  }
215}
216
217function toggleMe(obj) {
218  var id = obj.id.replace("toggle", "msg");
219  var t = document.getElementById(id);
220  if (obj.innerText == "+") {
221    obj.innerText = "-";
222    t.style.display = "block";
223  } else {
224    obj.innerText = "+";
225    t.style.display = "none";
226  }
227}
228
229</script>
230
231</head>
232<body>
233Server: <input type="text" id="server" value="http://localhost:8888" /><br>
234<input type="checkbox" id="loopback" checked="checked"/> Loopback (just send
235received messages right back)<br>
236Your name: <input type="text" id="local" value="my_name"/>
237<button id="connect" onclick="connect();">Connect</button>
238<button disabled="true" id="disconnect"
239        onclick="disconnect();">Disconnect</button>
240<br>
241<table><tr><td>
242Target peer id: <input type="text" id="peer_id" size="3"/></td><td>
243Message: <input type="text" id="message"/></td><td>
244<button disabled="true" id="send" onclick="send();">Send</button>
245</td></tr></table>
246<button onclick="document.getElementById('debug').innerHTML='';">
247Clear log</button>
248
249<pre id="debug">
250</pre>
251<br><hr>
252</body>
253</html>
254