Created
December 3, 2010 01:47
Toy server
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> | |
<head></head> | |
<body> | |
<p><textarea cols=100 rows=25 id="output"></textarea></p> | |
</body> | |
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> | |
<script type="text/javascript"> | |
var client = new function() { | |
var lastid=0; | |
var _poll = function(lastid) { | |
$.get('/foo?client=1&chan=7&last='+lastid, function(response) { | |
if(response.length > 0){ | |
$('textarea').text(response); | |
lastid = JSON.parse(response).reverse()[0].id; | |
} | |
_poll(lastid); // using reverse to get the latest head ID | |
}); | |
} | |
// Inital request | |
$.get('/foo?client=1&chan=7&last='+lastid, function(response) { | |
$('textarea').text(response); | |
lastid = JSON.parse(response).reverse()[0].id; | |
_poll(lastid); | |
}); | |
} | |
</script> | |
</html> |
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
config = module.exports = { | |
port : 8000, | |
redis: { | |
host: '127.0.0.1', | |
port: 6379 | |
}, | |
}; |
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 http = require('http'), | |
url = require('url'), | |
fs = require('fs'), | |
conf = require('./config'), | |
redis = require('redis'); | |
var Chan = function(id){ | |
var pubsub = redis.createClient(conf['redis']['port'], conf['redis']['host']); | |
var db = redis.createClient(conf['redis']['port'], conf['redis']['host']); | |
// A note on IDs. I use incrementing ints in the toy, but uuids in the syncpad server | |
var ID = 0; | |
var alterObj = function(obj){ | |
if(obj.eggs){ | |
delete obj.spam; | |
} | |
return obj; | |
}; | |
var startClient = function(response, clientId){ | |
pubsub.on('message', function(channel,record){ | |
obj = JSON.parse(record); | |
if(clientId != obj.client){ | |
obj = alterObj(obj); | |
// now back to a string for the client | |
response.write(JSON.stringify([obj])); | |
response.end(); | |
} | |
}); | |
setTimeout(function() { | |
response.end(); | |
}, 15000); | |
} | |
pubsub.subscribe(id); | |
return { | |
id:id, | |
foo: function(last, clientId, response){ | |
db.lrange(id, 0, 500, function(err, records){ | |
try{ | |
if(records != null){ | |
// In the syncpad server code, this actually maps 1000 elements, which could account for better performance in the toy server | |
var l = records.map(JSON.parse); | |
var curr = l[0].id; | |
if (last != curr){ | |
var objList = new Array(); | |
for (var i=0; i<l.length; i++){ | |
if(last == l[i].id){ | |
objList = objList.map(alterObj); | |
response.write(JSON.stringify(objList)); | |
break; | |
} else { | |
objList.unshift(l[i]); | |
} | |
} | |
response.end(); | |
} else { | |
startClient(response, clientId); | |
} | |
} else { | |
startClient(response,clientId); | |
} | |
} catch(error){ | |
response.end(); | |
} | |
}); | |
return; | |
}, | |
bar: function(query, response){ | |
try{ | |
var obj = { | |
id: ID++, | |
foo: query.foo, | |
bar: query.bar, | |
baz: query.baz, | |
spam: query.spam, | |
eggs: query.eggs, | |
client: query.client | |
}; | |
var value = JSON.stringify(obj); | |
db.publish(id, value); | |
db.lpush(id, value); | |
response.writeHead(201, {'Content-Type': 'text/plain'}); | |
}catch(error){ | |
response.writeHead(400, {'Content-Type': 'text/plain'}); | |
} | |
response.end(); | |
return; | |
}, | |
close: function(){ | |
db.end(); | |
pubsub.unsubscribe(); | |
pubsub.end(); | |
return; | |
} | |
} | |
} | |
var ToyServer = function(){ | |
var _self = this; | |
var chans = {}; | |
var handleFoo = function(req, res){ | |
// sample relative URI : "/foo?chan=7&client=1&last=4" | |
var query = url.parse(req.url,true).query; | |
var last = query.last; | |
var id = query.chan; | |
var clientId = query.client; | |
if (chans[id] === undefined){ | |
chans[id] = new Chan(id) | |
} | |
chan = chans[id]; | |
res.writeHead(200, {'Content-Type': 'text/plain'}); | |
chan.foo(last, clientId, res); | |
}; | |
var handleBar = function(req, res){ | |
// sample relative URI "/bar?foo=1&bar=2&baz=3&spam=4&eggs=5&client=6&chan=7" | |
var query = url.parse(req.url,true).query; | |
var id = query.chan; | |
if (chans[id] === undefined){ | |
chans[id] = new Chan(id) | |
} | |
chan = chans[id]; | |
chan.bar(query, res); | |
}; | |
var routes = { | |
'/foo': handleFoo, | |
'/bar': handleBar | |
}; | |
var _requestHandler = function(request, response) { | |
if(routes[url.parse(request.url).pathname] === undefined) { | |
response.writeHead(404, {'Content-Type': 'text/plain'}); | |
response.write('HTTP 404: Not Found\n'); | |
response.end(); | |
return; | |
} else { | |
routes[url.parse(request.url).pathname].call(this, request, response); | |
} | |
}; | |
var _server = http.createServer(). | |
addListener('request', _requestHandler) | |
.listen(conf.port); | |
console.log('Toy Server initialized at port '+conf.port); | |
}; | |
new ToyServer(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I forked this and editted it to use my multiserv library I wrote to run servers over multiple processes to use all 4 cores.
Try this: https://gist.github.com/735236