Created
May 16, 2012 08:38
-
-
Save noggs/2708744 to your computer and use it in GitHub Desktop.
node.js echo test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
var http = require('http'); | |
var fs = require('fs'); | |
var WebSocketServer = require('websocket').server; | |
var clients = []; | |
var next_client = 0; | |
var mainHtml = (function () { | |
var f; | |
try { | |
f = fs.readFileSync('main.html'); | |
} catch (e) {} | |
return f; | |
}()); | |
var server = http.createServer(function (req, res) { | |
// send our only page! | |
if (mainHtml !== undefined) { | |
res.writeHead(200, {'Content-Type': 'text/html'}); | |
res.end(mainHtml); | |
} else { | |
res.writeHead(404); | |
res.end(); | |
} | |
}).listen(1337); | |
console.log('Server running'); | |
var wsServer = new WebSocketServer({ | |
httpServer : server | |
}); | |
// WebSocket server | |
wsServer.on('request', function (request) { | |
var connection = request.accept(null, request.origin), | |
client_id, | |
sendClientList = function () { | |
// send client_list to everyone | |
var i, | |
msg = { | |
type : 'client_list', | |
clients : [] | |
}; | |
for (i in clients) { | |
if (clients.hasOwnProperty(i)) { | |
msg.clients.push(i); | |
} | |
} | |
for (i in clients) { | |
if (clients.hasOwnProperty(i)) { | |
msg.own_client_id = parseInt(i, 10); | |
clients[i].sendUTF(JSON.stringify(msg)); | |
} | |
} | |
}; | |
client_id = next_client += 1; | |
clients[client_id] = connection; | |
// This is the most important callback for us, we'll handle | |
// all messages from users here. | |
connection.on('message', function (message) { | |
var i, | |
response; | |
if (message.type === 'utf8') { | |
response = JSON.parse(message.utf8Data); | |
response.client_id = client_id; | |
response.type = 'echo'; | |
// echo message to all clients | |
response = JSON.stringify(response); | |
for (i in clients) { | |
if (clients.hasOwnProperty(i)) { | |
clients[i].sendUTF(response); | |
} | |
} | |
} | |
}); | |
connection.on('close', function (connection) { | |
// close user connection | |
delete clients[client_id]; | |
sendClientList(); | |
}); | |
// send updated client_list to everyone | |
sendClientList(); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
<title>Google App Engine - Channel API Test</title> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> | |
</head> | |
<body> | |
<div id="loggingArea" style="overflow:auto; height:400px;"> | |
</div> | |
<div id="results" style="height:200px;"> | |
<div> | |
<button type="button" id="send_button">SEND</button> | |
<button type="button" id="send5_button">SEND 5</button> | |
<input type="text" id="message" value="echo!" style="width:300px;"/> | |
</div> | |
<div> | |
<div> | |
Missing replies: <span id="missing_replies"></span> | |
</div> | |
<div> | |
Average latency: <span id="average_latency"></span> | |
</div> | |
<div> | |
Clients: [<span id="client_list"></span>] | |
</div> | |
</div> | |
</div> | |
<script> | |
/*global jQuery*/ | |
/*jslint browser: true, maxerr: 50, indent: 4*/ | |
(function () { | |
"use strict"; | |
jQuery(function () { | |
var logging = function (msg) { | |
var e = document.getElementById("loggingArea"); | |
e.innerHTML += '<br>' + msg; | |
e.scrollTop = e.scrollHeight; // auto scroll | |
}, | |
connected = false, | |
connection, | |
client_id, | |
clientSequence = 0, | |
clientSequences = [], | |
updateMissingReplies = function () { | |
var missingRepliesElement = document.getElementById("missing_replies"), | |
i; | |
missingRepliesElement.innerHTML = clientSequences.length.toString(); | |
for (i = 0; i < clientSequences.length; i += 1) { | |
if (i === 0) { | |
missingRepliesElement.innerHTML += " ["; | |
} | |
missingRepliesElement.innerHTML += clientSequences[i].toString(); | |
if (i === clientSequences.length - 1) { | |
missingRepliesElement.innerHTML += "]"; | |
} else { | |
missingRepliesElement.innerHTML += ", "; | |
} | |
} | |
}, | |
latencies = [], | |
updateAverageLatency = function (latency) { | |
var element = document.getElementById("average_latency"), | |
i, | |
avgStart, | |
runningAvg = 0, | |
runningAvgLength = 0, | |
numLatencies; | |
latencies.push(latency); | |
numLatencies = latencies.length; | |
avgStart = Math.max(0, numLatencies - 5); | |
runningAvgLength = numLatencies - avgStart; | |
for (i = avgStart; i < numLatencies; i += 1) { | |
runningAvg += latencies[i]; | |
} | |
runningAvg /= runningAvgLength; | |
element.innerHTML = runningAvg.toFixed(1) + 'ms'; | |
}, | |
sendMessage = function (msg) { | |
var data; | |
if (connected) { | |
data = { | |
clientSeq : clientSequence, | |
timestamp : Date.now(), | |
msg : msg | |
}; | |
connection.send(JSON.stringify(data)); | |
clientSequence += 1; | |
logging("SEND [" + data.clientSeq.toString() + "] \"" + data.msg + "\""); | |
clientSequences.push(data.clientSeq); | |
updateMissingReplies(); | |
} | |
}, | |
handleEcho = function (msg) { | |
var log_entry, | |
time = Date.now(), | |
total_latency, | |
replyIndex; | |
if (msg) { | |
msg.server_time = parseInt(msg.server_time, 10); | |
msg.timestamp = parseInt(msg.timestamp, 10); | |
total_latency = time - msg.timestamp; | |
log_entry = "RECV [" + msg.client_id + " " + msg.clientSeq.toString() + "]" + | |
" (" + total_latency.toString() + "ms)" + | |
" \"" + msg.msg + "\""; | |
logging(log_entry); | |
if (msg.client_id === client_id) { | |
replyIndex = clientSequences.indexOf(msg.clientSeq); | |
if (replyIndex !== -1) { | |
clientSequences.splice(replyIndex, 1); | |
} else { | |
logging("DUPLICATE MESSAGE RECEIVED"); | |
} | |
updateMissingReplies(); | |
updateAverageLatency(total_latency); | |
} | |
} | |
}, | |
handleClientList = function (msg) { | |
var element = document.getElementById('client_list'), | |
i, | |
str = "", | |
own_id_str = ""; | |
if (msg.clients instanceof Array) { | |
for (i = 0; i < msg.clients.length; i += 1) { | |
if (i > 0) { | |
str += ", "; | |
} | |
str += msg.clients[i]; | |
} | |
} | |
if (msg.own_client_id !== undefined) { | |
client_id = msg.own_client_id; | |
own_id_str = client_id.toString(); | |
} | |
element.innerHTML = str; | |
logging("RECV client_list [" + str + "] (" + own_id_str + ")"); | |
}, | |
message_handlers = { | |
'echo' : handleEcho, | |
'client_list' : handleClientList | |
}, | |
WebSocket = window.WebSocket || window.MozWebSocket; | |
logging("Connecting to server..."); | |
connection = new WebSocket('ws://echo_test.jit.su'); | |
//connection = new WebSocket('ws://127.0.0.1:1337'); | |
connection.onopen = function () { | |
connected = true; | |
logging("==============================================="); | |
logging("Connected"); | |
}; | |
connection.onerror = function (error) { | |
logging("error (" + error.code + ": " + error.description); | |
}; | |
connection.onclose = function () { | |
connected = false; | |
logging("Disconnected from [" + client_id + "]"); | |
logging("==============================================="); | |
}; | |
connection.onmessage = function (msg) { | |
var data = jQuery.parseJSON(msg.data), | |
handler; | |
if (data !== undefined) { | |
handler = message_handlers[data.type]; | |
if (handler !== undefined) { | |
handler(data); | |
} else { | |
logging("unhandled message type: " + data.type); | |
} | |
} else { | |
logging("ignoring malformed message: " + msg); | |
} | |
}; | |
document.getElementById('send_button').onclick = function () { | |
var msg = document.getElementById('message').value; | |
sendMessage(msg); | |
}; | |
document.getElementById('send5_button').onclick = function () { | |
var msg = document.getElementById('message').value, | |
i; | |
for (i = 0; i < 5; i += 1) { | |
sendMessage(msg); | |
} | |
}; | |
}); | |
}()); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment