-
-
Save anonymous/766833e32b319755c47b to your computer and use it in GitHub Desktop.
Basic testing of SockJS-node connections and message passing.
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
var sockJsTest = (function sockJsTest() { | |
var | |
socketData, | |
ieversion, | |
socket = null; | |
hearbeatInterval = null; | |
reportTimeout = null; | |
useSSL = true, | |
sendOnConnect = "", | |
ajaxFile = "/system/ajax/ajax.Vine.php", | |
domain = "sockjs.example.com", | |
server = "https://" + domain + ":4002/sockjs"; | |
// Determine server address | |
if ( useSSL ) { | |
// Even though we want to use SSL, IE 9- won't allow that | |
// on http:// pages. | |
if ( /MSIE (\d+\.\d+);/.test( navigator.userAgent ) ) { | |
if ( window.location.protocol === "http:" ) { | |
ieversion = new Number( RegExp.$1 ); | |
if ( ieversion <= 9 ) { | |
server = "http://" + domain + ":4000/sockjs"; | |
} | |
} | |
} | |
} else if ( window.location.protocol === "http:" ) { | |
server = "http://" + domain + ":4000/sockjs"; | |
} | |
// Data that will be reported back | |
socketData = { | |
connects : 0, | |
disconnects : 0, | |
messages : 0, | |
errors : 0, | |
time : new Date().getTime() | |
}; | |
// This is what will be sent to the server upon connect. | |
// The server will reply with an acknowledgement. | |
sendOnConnect = JSON.stringify({ | |
__event : "information", | |
url : window.location.href, | |
agent : navigator.userAgent | |
}); | |
// | |
// Log results once user has been on page for 8 seconds. | |
// While it is possible a user connects after 8 seconds, | |
// we consider that a failure, since we never want to | |
// wait that long. | |
// | |
reportTimeout = setTimeout( function() { | |
if ( socketData.connects <= 0 ) { | |
socketData.time = 0; | |
} | |
var data = { | |
action : "report", | |
data : JSON.stringify( socketData ), | |
transport : socket.protocol, | |
url : window.location.href, | |
server : "sockjs" | |
}; | |
$.post( ajaxFile, data ); | |
}, 8000 ); | |
socket = new SockJS( server, false, {} ); | |
socket.onopen = function() { | |
socketData.connects++; | |
socketData.time = new Date().getTime() - socketData.time; | |
// Send data 1/2 second after connect. We add this delay | |
// just to give the client and server some time to finish | |
// any needed processing. Techinically, we shouldn't need | |
// the timeout. | |
setTimeout( function() { | |
socket.send( sendOnConnect ); | |
}, 500 ); | |
// Send heartbeat every 30 seconds. This allows us | |
// to force close a connection that isn't dropped | |
// right away or perform whatever other logic we | |
// might want to do when the server doesn't see me. | |
heartbeatInterval = setInterval( function() { | |
socket.send( JSON.stringify( { __event : "heartbeat" } ) ); | |
}, 30000 ); | |
}; | |
socket.onmessage = function(data) { | |
socketData.messages++; | |
}; | |
socket.onclose = function() { | |
socketData.disconnects++; | |
}; | |
return { | |
beforeUnload : function() { | |
if ( socket ) { | |
socket.close(); | |
} | |
if ( heartbeatInterval ) { | |
clearInterval( heartbeatInterval ); | |
} | |
if ( reportTimeout ) { | |
clearTimeout( reportTimeout ); | |
} | |
} | |
}; | |
})(); | |
// *sigh* Why do so many pages use old jQuery? | |
// Hopefully this won't screw something else up - like dialogs | |
$(document).bind("keypress", function(e) { | |
if (e.keyCode === 27) { | |
return false; | |
} | |
}); | |
window.onbeforeunload = function() { | |
sockJsTest.beforeUnload(); | |
}; |
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
var | |
os = require("os"), | |
fs = require("fs"), | |
util = require("util"), | |
http = require("http"), | |
https = require("https"), | |
fs = require("fs"), | |
express = require("express"), | |
sockjs = require("sockjs"), | |
moment = require("moment"), | |
Log = require("log"), | |
tinycolor = require("tinycolor"); | |
var | |
startTime = Date.now(), | |
web = express(), | |
sockjsHttp, sockjsHttps; | |
// | |
// Set up logging right away so we can log anything! | |
// | |
log = new Log("info", fs.createWriteStream("log.txt")); | |
// | |
// Cleans unused SockJS connections. | |
// | |
setInterval(function() { | |
var | |
id, | |
expires = Date.now() - 900000; | |
for (id in sockets) { | |
if (clients[id].activity < expires) { | |
log.error("Force close " + id); | |
console.log("Force close " + id); | |
counters.forceClose += 1; | |
sockets[id].close(); | |
} | |
} | |
}, 70000); | |
// | |
// Client list. Information about each client. | |
// | |
var clients = {}; | |
// | |
// Socket list. This is the actual SockJS socket object | |
// | |
var sockets = {} | |
// | |
// Counters | |
// | |
counters = { | |
packetsReceived : 0, | |
bytesReceived : 0, | |
packetsSent : 0, | |
bytesSent : 0, | |
connects : 0, | |
disconnects : 0, | |
current : 0, | |
errors : 0, | |
forceClose : 0 | |
}; | |
/*************************************************************************** | |
____ ____ _ | |
/ ___| ___ _ ____ _____ _ __ / ___| ___| |_ _ _ _ __ | |
\___ \ / _ \ '__\ \ / / _ \ '__| \___ \ / _ \ __| | | | '_ \ | |
___) | __/ | \ V / __/ | ___) | __/ |_| |_| | |_) | | |
|____/ \___|_| \_/ \___|_| |____/ \___|\__|\__,_| .__/ | |
|_| | |
***************************************************************************/ | |
(function() { | |
var httpServer, httpsServer; | |
// | |
// Web server | |
// | |
var sslOpts = { | |
key : fs.readFileSync( "ssl.key" ), | |
cert : fs.readFileSync( "ssl.crt" ) | |
}; | |
httpServer = http.createServer(web); | |
httpsServer = https.createServer(sslOpts, web); | |
var port = process.argv[2] || 4000; | |
if (port < 1024 && process.getuid() !== 0) { | |
console.log(("Must run server as root for ports below 1024.").red); | |
process.exit(1); | |
} | |
httpServer.listen(port); | |
httpsServer.listen(port + 2); | |
var sockjsOpts = { | |
sockjs_url : "http://cdn.sockjs.org/sockjs-0.3.min.js" | |
} | |
sockjsHttp = sockjs.createServer(sockjsOpts); | |
sockjsHttps = sockjs.createServer(sockjsOpts); | |
sockjsHttp.installHandlers(httpServer, { prefix : '/sockjs' }); | |
sockjsHttps.installHandlers(httpsServer, { prefix : '/sockjs' }); | |
console.log(("SockJS/Express Load Test listening on port " + port + ".").green); | |
console.log(("SSL listening on port " + (port + 2) + ".").green); | |
})(); | |
// Remove root privs after ports have been setup | |
if (process.getuid() === 0) { | |
process.setuid("ec2-user"); | |
} | |
/*************************************************************************** | |
____ _ | |
| _ \ ___ _ _| |_ ___ _ __ ___ | |
| |_) / _ \| | | | __/ _ \ '__/ __| | |
| _ < (_) | |_| | || __/ | \__ \ | |
|_| \_\___/ \__,_|\__\___|_| |___/ | |
***************************************************************************/ | |
web.get("/", function(req, res) { | |
res.send("SockJS/Express test server"); | |
}); | |
web.get("/stats", function(req, res) { | |
res.json([counters, clients]); | |
}); | |
web.get("/kill/:id", function(req, res) { | |
var id = req.params['id']; | |
if (clients.hasOwnProperty(id) && sockets.hasOwnProperty(id)) { | |
sockets[id].close(); | |
res.send("Killed " + id); | |
} else { | |
res.send("Invalid id " + id); | |
} | |
}); | |
/*************************************************************************** | |
____ _ _ _____ _ | |
/ ___| ___ ___| | _____| |_ | ____|_ _____ _ __ | |_ ___ | |
\___ \ / _ \ / __| |/ / _ \ __| | _| \ \ / / _ \ '_ \| __/ __| | |
___) | (_) | (__| < __/ |_ | |___ \ V / __/ | | | |_\__ \ | |
|____/ \___/ \___|_|\_\___|\__| |_____| \_/ \___|_| |_|\__|___/ | |
***************************************************************************/ | |
attach(sockjsHttp); | |
attach(sockjsHttps); | |
function attach(server) { | |
server.on("connection", function(socket) { | |
if (!socket) return; | |
counters.connects += 1; | |
counters.current += 1; | |
clients[socket.id] = { | |
id : socket.id, | |
connected : moment().format("MMMM Do YYYY, h:mm:ss a"), | |
activity : Date.now() | |
} | |
sockets[socket.id] = socket; | |
socket.on("data", function(data) { | |
var json; | |
counters.packetsReceived += 1; | |
counters.bytesReceived += data.length; | |
try { | |
json = JSON.parse(data); | |
} catch (ex) { | |
return; | |
} | |
if (json.hasOwnProperty("__event")) | |
{ | |
if (json.__event === "information") { | |
delete json.__event; | |
for (var property in json) { | |
clients[socket.id][property] = json[property]; | |
} | |
} | |
// Respond with a dumb acknowledgement | |
counters.packetsSent += 1; | |
counters.bytesSent += socket.id.length; | |
socket.write(socket.id); | |
} | |
// Update client activity information | |
if (clients.hasOwnProperty(socket.id)) { | |
clients[socket.id].activity = Date.now(); | |
clients[socket.id].lastActive = moment().format("MMMM Do YYYY, h:mm:ss a"); | |
} | |
}); | |
// Probably not a valid event - could not find in docs | |
socket.on("error", function(err) { | |
counters.errors += 1; | |
log.error("error", "Socket error: " + err.toString()); | |
}); | |
socket.on("close", function() { | |
// Seems to help memory | |
socket.removeAllListeners(); | |
counters.disconnects += 1; | |
counters.current -= 1; | |
if (clients.hasOwnProperty(this.id)) { | |
delete clients[this.id]; | |
} | |
if (sockets.hasOwnProperty(this.id)) { | |
delete sockets[this.id]; | |
} | |
}); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment