1 <html> 2 <head> 3 <title>PeerConnection server test page</title> 4 5 <script> 6 var request = null; 7 var hangingGet = null; 8 var localName; 9 var server; 10 var my_id = -1; 11 var other_peers = {}; 12 var message_counter = 0; 13 14 function trace(txt) { 15 var elem = document.getElementById("debug"); 16 elem.innerHTML += txt + "<br>"; 17 } 18 19 function 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 26 function handlePeerMessage(peer_id, data) { 27 ++message_counter; 28 var str = "Message from '" + other_peers[peer_id] + "' "; 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 63 function GetIntHeader(r, name) { 64 var val = r.getResponseHeader(name); 65 return val != null && val.length ? parseInt(val) : -1; 66 } 67 68 function 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 96 function 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 108 function 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 116 function 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 139 function 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 150 function 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 167 function 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 181 function 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 205 window.onbeforeunload = disconnect; 206 207 function 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 217 function 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> 233 Server: <input type="text" id="server" value="http://localhost:8888" /><br> 234 <input type="checkbox" id="loopback" checked="checked"/> Loopback (just send 235 received messages right back)<br> 236 Your 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> 242 Target peer id: <input type="text" id="peer_id" size="3"/></td><td> 243 Message: <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='';"> 247 Clear log</button> 248 249 <pre id="debug"> 250 </pre> 251 <br><hr> 252 </body> 253 </html> 254