mirror of
https://github.com/amark/gun.git
synced 2025-06-22 22:12:33 +00:00
gun slinger!
This commit is contained in:
parent
bfd11b9115
commit
cf386e3ced
@ -1,15 +1,19 @@
|
|||||||
console.log("If modules not found, run `npm install` in example/admin folder!"); // git subtree push -P examples/admin heroku master
|
console.log("If modules not found, run `npm install` in example/admin folder!"); // git subtree push -P examples/admin heroku master
|
||||||
var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || 8888;
|
var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || 8888;
|
||||||
var express = require('express');
|
var express = require('connect');
|
||||||
var bodyParser = require('body-parser');
|
var bodyParser = require('body-parser');
|
||||||
var app = express();
|
var app = express();
|
||||||
var Gun = require('gun');
|
var Gun = require('gun');
|
||||||
var gun = Gun({
|
var gun = Gun({
|
||||||
s3: (process.env.NODE_ENV === 'production')? null : require('../../test/shotgun') // replace this with your own keys!
|
s3: (process.env.NODE_ENV === 'production')? null : require('../../test/shotgun') // replace this with your own keys!
|
||||||
});
|
});
|
||||||
|
app.use(function(req, res, next){
|
||||||
app.use(gun.server)
|
console.log("THIS HIT SEEEERVER", req.url);
|
||||||
.use(express.static(__dirname))
|
next();
|
||||||
|
})
|
||||||
|
.use(gun.server)
|
||||||
|
.use(require('serve-static')(__dirname))
|
||||||
|
//.use(express.static(__dirname))
|
||||||
app.listen(port);
|
app.listen(port);
|
||||||
|
|
||||||
console.log('Express started on port ' + port + ' with /gun');
|
console.log('Express started on port ' + port + ' with /gun');
|
||||||
|
@ -29,52 +29,183 @@
|
|||||||
.none {
|
.none {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
.fight {
|
||||||
|
z-index: 9999;
|
||||||
|
background: brown;
|
||||||
|
color: white;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
.player input, .player button {
|
||||||
|
font-size: 18pt;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<h2>Gun Duel!</h2>
|
<h2><i>GUNSLINGER</i></h2>
|
||||||
<span>Old western cowboy style! Two players are needed, whoever can shoot the other first wins!</span>
|
<span>Old West Duel! Two players are needed, whoever can tap the screen first to draw their pistol and shoot wins!</span><br>
|
||||||
<span><b>Fastest gun in the west, <span name="fastest">nut'n</span> by <span name="slinger">nobody</span>.</b></span>
|
<span><b>Fastest gun in the west, <span name="fastest">nut'n</span> seconds, by <span name="slinger">nobody</span>.</b></span>
|
||||||
<form id="p1" class="assign-player" onsubmit="return false;">
|
<form id="p1" class="player" onsubmit="return false;">
|
||||||
Player 1: <input type="text" name="p1" class="player" placeholder="nickname">
|
Player 1: <input type="text" name="p1" placeholder="nickname"> <button type="submit">Join!</button>
|
||||||
<input type="submit" class="take" value="Join!">
|
|
||||||
</form>
|
</form>
|
||||||
<form id="p2" class="assign-player" onsubmit="return false;">
|
<form id="p2" class="player" onsubmit="return false;">
|
||||||
Player 2: <input type="text" name="p2" class="player" placeholder="nickname">
|
Player 2: <input type="text" name="p2" placeholder="nickname"> <button type="submit">Join!</button>
|
||||||
<input type="submit" class="take" value="Join!">
|
|
||||||
</form>
|
</form>
|
||||||
<div id="duel">
|
<div id="duel" class="none fight">
|
||||||
|
<center>
|
||||||
|
<h2>GET READY!</h2>
|
||||||
|
<button id="reset" class="none">
|
||||||
|
Reset the game!
|
||||||
|
</button>
|
||||||
|
</center>
|
||||||
</div>
|
</div>
|
||||||
|
<span><b>Last duel won by <span name="last">no one</span> in <span name="ended">0</span> seconds against <span name="loser">nobody</span>.</b></span>
|
||||||
<script>
|
<script>
|
||||||
(function(){
|
$(function(){
|
||||||
var me = {},
|
var me = window.me = {},
|
||||||
gun = Gun(['http://localhost:8888/' + 'gun'])
|
game = window.game = {},
|
||||||
.load('game/duel', function(game){
|
//gun = window.gun = Gun(['http://localhost:8888/' + 'gun'])
|
||||||
console.log(game);
|
gun = window.gun = Gun(['http://gunduel.t.proxylocal.com/' + 'gun'])
|
||||||
$(document).on('submit', '.assign-player', function(e){
|
.load('game/duel', function(data){
|
||||||
|
console.log(data);
|
||||||
|
$(document).on('submit', '.player', function(e){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var nick = $(this).find('input').val();
|
var nick = $(this).find('input').val(), id = this.id;
|
||||||
if(!nick){ return }
|
if(!nick || me.player){ return }
|
||||||
gun.path(this.id).get(function(val){
|
gun.path(id).get(function(val){
|
||||||
if(val){ return }
|
if(val){ return }
|
||||||
gun.path(this.id).set(me.player = nick);
|
this.set(me.player = nick);
|
||||||
|
me.took = id;
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
Gun.on(game._[Gun.sym.id]).event(function(node){
|
Gun.on(data._[Gun.sym.id]).event(function(node, local){
|
||||||
|
if(!node){ return }
|
||||||
console.log("change!", node);
|
console.log("change!", node);
|
||||||
|
if(node.start){ game.schedule(node.start) }
|
||||||
|
if(node.dqed){ game.dq(node.dqed) }
|
||||||
|
if(node.sling){ game.sling(node.sling, local) }
|
||||||
|
Gun.obj.map(node, game.set);
|
||||||
|
if(node.p1 || node.p2){
|
||||||
|
gun.path('p1').get(function(p1){ // start game?
|
||||||
|
if(!p1){ return }
|
||||||
|
gun.path('p2').get(function(p2){
|
||||||
|
if(!p2){ return }
|
||||||
|
game.play(p2);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
game.timeout(true);
|
||||||
});
|
});
|
||||||
Gun.obj.map(game, me.set);
|
Gun.obj.map(data, game.set);
|
||||||
|
game.timeout(20);
|
||||||
});
|
});
|
||||||
me.set = function(val, name){
|
game.$duel = $("#duel");
|
||||||
|
game.$duelm = game.$duel.clone();
|
||||||
|
game.play = function(p2){
|
||||||
|
if(!me.player){ return }
|
||||||
|
game.$duel.removeClass("none");
|
||||||
|
if(me.player == p2){ return }
|
||||||
|
me.scheduled = (+new Date()) + Math.round(Math.random() * 2000 + 2700); // MIN is the right number, and MAX is the SUM of both numbers.
|
||||||
|
gun.path('start').set(me.scheduled);
|
||||||
|
}
|
||||||
|
game.schedule = function(at){
|
||||||
|
console.log(" ------------------ START", at);
|
||||||
|
if(me.started){ return }
|
||||||
|
me.started = true;
|
||||||
|
me.scheduled = at;
|
||||||
|
Gun.schedule(at, function(){
|
||||||
|
me.shoot = true;
|
||||||
|
if(me.dqed){ return }
|
||||||
|
game.$duel.css({background: 'lime'}).find('h2').text("FIRE!");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
game.fire = function(){
|
||||||
|
if(!me.started || me.fired){ return }
|
||||||
|
me.fired = (+ new Date());
|
||||||
|
if(me.fired < me.scheduled){ // DQ
|
||||||
|
me.dqed = me.player;
|
||||||
|
gun.path('dqed').set(me.player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gun.path('dqed').get(function(yes){
|
||||||
|
if(yes){ return }
|
||||||
|
game.$duel.css({background: 'gold'}).find('h2').text("STOP!");
|
||||||
|
gun.path('sling').set(me.player);
|
||||||
|
me.time = (me.fired - me.scheduled) / 1000; // in seconds
|
||||||
|
});
|
||||||
|
}
|
||||||
|
game.sling = function(){
|
||||||
|
me.count = (me.count || 0) + 1;
|
||||||
|
if(me.count < 2){ return }
|
||||||
|
$('#reset').removeClass('none');
|
||||||
|
gun.path('sling').get(function(sling){
|
||||||
|
if(!sling){ return }
|
||||||
|
if(sling == me.player){
|
||||||
|
game.$duel.css({background: 'red'}).find('h2').text("YOU DIED!!!");
|
||||||
|
gun.path('loser').set(me.player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
game.$duel.css({background: 'skyblue'}).find('h2').text("YOU WON!!!");
|
||||||
|
if(!me.time || me.fired < me.scheduled || me.time < 0){ return }
|
||||||
|
gun.path('last').set(me.player);
|
||||||
|
gun.path('ended').set(me.time);
|
||||||
|
gun.path('fastest').get(function(time){
|
||||||
|
if(time <= me.time){ return }
|
||||||
|
gun.path('fastest').set(me.time);
|
||||||
|
gun.path('slinger').set(me.player);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
game.dq = function(who){
|
||||||
|
$('#reset').removeClass('none');
|
||||||
|
if(who == me.player){
|
||||||
|
return game.$duel.css({background: 'gray'}).find('h2').text("DISQUALIFIED!!!");
|
||||||
|
}
|
||||||
|
if(me.dqed){
|
||||||
|
return game.$duel.find('h2').text("BOTH DISQUALIFIED!");
|
||||||
|
}
|
||||||
|
game.$duel.css({background: 'skyblue'}).find('h2').text("YOU WON!!!");
|
||||||
|
}
|
||||||
|
game.clear = function(){
|
||||||
|
me = {};
|
||||||
|
game.$duel.replaceWith(game.$duel = game.$duelm.clone());
|
||||||
|
gun.path('p1').set("");
|
||||||
|
gun.path('p2').set("");
|
||||||
|
gun.path('sling').set(null);
|
||||||
|
gun.path('start').set(null);
|
||||||
|
gun.path('dq').set(null);
|
||||||
|
game.$duel.addClass('none');
|
||||||
|
}
|
||||||
|
game.timeout = function(wait){
|
||||||
|
if(true === wait){ return clearTimeout(me.timeout) }
|
||||||
|
wait = wait || 15;
|
||||||
|
clearTimeout(me.timeout);
|
||||||
|
me.timeout = setTimeout(game.clear, wait * 1000);
|
||||||
|
}
|
||||||
|
game.set = function(val, name){
|
||||||
|
if(val == game.nothing){ return }
|
||||||
$("[name='" + name + "']").text(val).val(val);
|
$("[name='" + name + "']").text(val).val(val);
|
||||||
Gun.on("duel-" + name).emit(val, name);
|
Gun.on("duel-" + name).emit(val, name);
|
||||||
}
|
}
|
||||||
me.plock = function(val, id){
|
game.plock = function(val, id){
|
||||||
console.log("OH?", val, id);
|
$("#" + id).find('input').attr("readonly", val? true : false);
|
||||||
$("#" + id).find('.player').attr("readonly", val? true : false);
|
$("#" + id).find('button').text(val? "Taken!" : "Join!").attr("disabled", val? true : false);
|
||||||
$("#" + id).find('.take').val(val? "Taken!" : "Join!").attr("disabled", val? true : false);
|
|
||||||
}
|
}
|
||||||
Gun.on("duel-p1").event(me.plock);
|
Gun.on("duel-p1").event(game.plock);
|
||||||
Gun.on("duel-p2").event(me.plock);
|
Gun.on("duel-p2").event(game.plock);
|
||||||
|
$(document).on('click', '#duel', game.fire);
|
||||||
|
$(document).on('click', '#reset', game.clear);
|
||||||
|
}());
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
(function(){
|
||||||
|
return;
|
||||||
|
var game = Gun(location + 'gun').load('game/duel');
|
||||||
|
game.on('change').path('p1').or.path('p2').get(function(val){
|
||||||
|
$("#" + this.field).find('input').val(val? "Taken!" : "Join!").attr("disabled", val? true : false);
|
||||||
|
$("#" + this.field).find('button').val(val? "Taken!" : "Join!").attr("disabled", val? true : false);
|
||||||
|
});
|
||||||
}());
|
}());
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
79
gun.js
79
gun.js
@ -95,8 +95,8 @@
|
|||||||
}
|
}
|
||||||
Gun.chain.path = function(path){ // The focal point follows the path
|
Gun.chain.path = function(path){ // The focal point follows the path
|
||||||
var gun = this.chain();
|
var gun = this.chain();
|
||||||
path = path.split('.');
|
path = (path||'').split('.');
|
||||||
Gun.log("PATH stack trace", gun._.events.trace + 1, 'was it before loaded?', this._);
|
Gun.log("PATH stack trace", path, gun._.events.trace + 1, 'was it before loaded?', this._);
|
||||||
gun._.events.on(gun._.events.trace += 1).event(function trace(node){
|
gun._.events.on(gun._.events.trace += 1).event(function trace(node){
|
||||||
Gun.log("stack at", gun._.events.at);
|
Gun.log("stack at", gun._.events.at);
|
||||||
if(!path.length){ // if the path resolves to another node, we finish here
|
if(!path.length){ // if the path resolves to another node, we finish here
|
||||||
@ -131,9 +131,9 @@
|
|||||||
gun._.events.on(gun._.events.trace += 1).event(function(node){
|
gun._.events.on(gun._.events.trace += 1).event(function(node){
|
||||||
console.log("BOOM got it", node);
|
console.log("BOOM got it", node);
|
||||||
if(gun._.field){
|
if(gun._.field){
|
||||||
return cb((node||{})[gun._.field]); // copy data first?
|
return cb.call(gun, (node||{})[gun._.field]); // copy data first?
|
||||||
}
|
}
|
||||||
cb(Gun.obj.copy(node)); // we do here.
|
cb.call(gun, Gun.obj.copy(node)); // we do here.
|
||||||
});
|
});
|
||||||
if(gun._.loaded){
|
if(gun._.loaded){
|
||||||
gun._.events.at -= 1; // IDK why we are doing this, just trying to get something to work.
|
gun._.events.at -= 1; // IDK why we are doing this, just trying to get something to work.
|
||||||
@ -428,7 +428,7 @@
|
|||||||
var serverState = Gun.time.is();
|
var serverState = Gun.time.is();
|
||||||
// add more checks?
|
// add more checks?
|
||||||
var state = HAM(serverState, deltaStates[field], states[field], deltaValue, current[field]);
|
var state = HAM(serverState, deltaStates[field], states[field], deltaValue, current[field]);
|
||||||
// Gun.log("HAM:", field, deltaValue, deltaStates[field], current[field], 'the', state, (deltaStates[field] - serverState));
|
//console.log("HAM:", field, deltaValue, deltaStates[field], current[field], 'the', state, (deltaStates[field] - serverState));
|
||||||
if(state.err){
|
if(state.err){
|
||||||
Gun.log(".!HYPOTHETICAL AMNESIA MACHINE ERR!.", state.err);
|
Gun.log(".!HYPOTHETICAL AMNESIA MACHINE ERR!.", state.err);
|
||||||
return;
|
return;
|
||||||
@ -615,7 +615,7 @@
|
|||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
Gun.log = function(a, b, c, d, e, f){ //s, l){
|
Gun.log = function(a, b, c, d, e, f){ //s, l){
|
||||||
console.log(a, b, c, d, e, f);
|
//console.log(a, b, c, d, e, f);
|
||||||
//console.log.apply(console, arguments);
|
//console.log.apply(console, arguments);
|
||||||
}
|
}
|
||||||
own.sym = Gun.sym = {
|
own.sym = Gun.sym = {
|
||||||
@ -637,7 +637,7 @@
|
|||||||
tab.server = tab.server || function(req, res, next){
|
tab.server = tab.server || function(req, res, next){
|
||||||
|
|
||||||
}
|
}
|
||||||
window.tab = tab; //window.XMLHttpRequest = null; // for debugging purposes
|
window.tab = tab; // window.XMLHttpRequest = null; // for debugging purposes
|
||||||
(function(){
|
(function(){
|
||||||
tab.store = {};
|
tab.store = {};
|
||||||
var store = window.localStorage || {setItem: function(){}, removeItem: function(){}, getItem: function(){}};
|
var store = window.localStorage || {setItem: function(){}, removeItem: function(){}, getItem: function(){}};
|
||||||
@ -659,7 +659,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
(function(){
|
(function(){
|
||||||
tab.subscribe.sub = (reply.headers || {})['gun-sub'];
|
tab.subscribe.sub = (reply.headers || {})['gun-sub'] || tab.subscribe.sub;
|
||||||
//console.log("We are sub", tab.subscribe.sub);
|
//console.log("We are sub", tab.subscribe.sub);
|
||||||
var data = reply.body;
|
var data = reply.body;
|
||||||
if(!data || !data._){ return }
|
if(!data || !data._){ return }
|
||||||
@ -668,23 +668,44 @@
|
|||||||
}, {headers: {'Gun-Sub': tab.subscribe.sub || ''}, header: {'Gun-Sub': 1}});
|
}, {headers: {'Gun-Sub': tab.subscribe.sub || ''}, header: {'Gun-Sub': 1}});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
tab.url = function(nodes){
|
||||||
|
return;
|
||||||
|
console.log("urlify delta", nodes);
|
||||||
|
var s = ''
|
||||||
|
, uri = encodeURIComponent;
|
||||||
|
Gun.obj.map(nodes, function(delta, id){
|
||||||
|
var ham;
|
||||||
|
if(!delta || !delta._ || !(ham = delta._[Gun.sym.HAM])){ return }
|
||||||
|
s += uri('#') + '=' + uri(id) + '&';
|
||||||
|
Gun.obj.map(delta, function(val, field){
|
||||||
|
if(field === Gun.sym.meta){ return }
|
||||||
|
s += uri(field) + '=' + uri(Gun.text.ify(val)) + uri('>') + uri(ham[field]) + '&';
|
||||||
|
})
|
||||||
|
});
|
||||||
|
console.log(s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
tab.set = tab.set || function(nodes, cb){
|
tab.set = tab.set || function(nodes, cb){
|
||||||
cb = cb || function(){};
|
cb = cb || function(){};
|
||||||
// TODO: batch and throttle later.
|
// TODO: batch and throttle later.
|
||||||
tab.store.set(respond.id = 'send/' + Gun.text.random(), nodes);
|
tab.store.set(cb.id = 'send/' + Gun.text.random(), nodes);
|
||||||
//console.log("localStorage the DELTA", nodes);
|
//tab.url(nodes);
|
||||||
Gun.obj.map(gun.__.opt.peers, function(peer, url){
|
Gun.obj.map(gun.__.opt.peers, function(peer, url){
|
||||||
tab.ajax(url, nodes, respond, {headers: {'Gun-Sub': tab.subscribe.sub || ''}});
|
tab.ajax(url, nodes, function respond(err, reply, id){
|
||||||
});
|
var body = reply && reply.body;
|
||||||
function respond(err, reply, id){
|
respond.id = respond.id || cb.id;
|
||||||
if(reply && reply.body){
|
Gun.obj.del(tab.set.defer, id); // handle err with a retry? Or make a system auto-do it?
|
||||||
if(reply.body.defer){
|
if(!body){ return }
|
||||||
tab.set.defer[reply.body.defer] = respond;
|
if(body.defer){
|
||||||
|
console.log("deferring post", body.defer);
|
||||||
|
tab.set.defer[body.defer] = respond;
|
||||||
}
|
}
|
||||||
if(reply.body.refed || reply.body.reply){
|
if(body.reply){
|
||||||
//console.log("-------post-reply-all--------->", reply, err);
|
respond(null, {headers: reply.headers, body: body.reply });
|
||||||
respond(null, {headers: reply.headers, body: reply});
|
}
|
||||||
Gun.obj.map(reply.body.refed, function(r, id){
|
if(body.refed){
|
||||||
|
console.log("-------post-reply-all--------->", reply, err);
|
||||||
|
Gun.obj.map(body.refed, function(r, id){
|
||||||
var cb;
|
var cb;
|
||||||
if(cb = tab.set.defer[id]){
|
if(cb = tab.set.defer[id]){
|
||||||
cb(null, {headers: reply.headers, body: r}, id);
|
cb(null, {headers: reply.headers, body: r}, id);
|
||||||
@ -693,11 +714,13 @@
|
|||||||
// TODO: should be able to do some type of "checksum" that every request cleared, and if not, figure out what is wrong/wait for finish.
|
// TODO: should be able to do some type of "checksum" that every request cleared, and if not, figure out what is wrong/wait for finish.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('callback complete, now respond', respond.id);
|
if(body.reply || body.defer || body.refed){ return }
|
||||||
tab.store.del(respond.id);
|
tab.store.del(respond.id);
|
||||||
}
|
}, {headers: {'Gun-Sub': tab.subscribe.sub || ''}});
|
||||||
Gun.obj.del(tab.set.defer, id);
|
});
|
||||||
}
|
Gun.obj.map(nodes, function(node, id){
|
||||||
|
Gun.on(id).emit(node, true); // TODO: Temporary hack, I want to rebroadcast back to ourselves. IDK if this is always useful, and we shouldn't use global.
|
||||||
|
});
|
||||||
}
|
}
|
||||||
tab.set.defer = {};
|
tab.set.defer = {};
|
||||||
tab.subscribe = function(id){ // TODO: BUG!!! ERROR! Handle disconnection (onerror)!!!!
|
tab.subscribe = function(id){ // TODO: BUG!!! ERROR! Handle disconnection (onerror)!!!!
|
||||||
@ -711,10 +734,14 @@
|
|||||||
'Gun-Sub': tab.subscribe.sub || ''
|
'Gun-Sub': tab.subscribe.sub || ''
|
||||||
}
|
}
|
||||||
}, query = tab.subscribe.sub? '' : tab.subscribe.query(tab.subscribe.to);
|
}, query = tab.subscribe.sub? '' : tab.subscribe.query(tab.subscribe.to);
|
||||||
|
console.log("subscribing poll", tab.subscribe.sub);
|
||||||
Gun.obj.map(gun.__.opt.peers, function(peer, url){
|
Gun.obj.map(gun.__.opt.peers, function(peer, url){
|
||||||
tab.ajax(url + query, null, function(err, reply){
|
tab.ajax(url + query, null, function(err, reply){
|
||||||
//console.log("poll", err, reply);
|
if(err || !reply || !reply.body || reply.body.err){ // not interested in any null/0/''/undefined values
|
||||||
if(!reply || !reply.body){ return } // not interested in any null/0/''/undefined values
|
console.log(err, reply);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("poll", reply);
|
||||||
tab.subscribe.poll();
|
tab.subscribe.poll();
|
||||||
if(reply.headers){
|
if(reply.headers){
|
||||||
tab.subscribe.sub = reply.headers['gun-sub'] || tab.subscribe.sub;
|
tab.subscribe.sub = reply.headers['gun-sub'] || tab.subscribe.sub;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{ "name": "gun"
|
{ "name": "gun"
|
||||||
, "version": "0.0.6"
|
, "version": "0.0.6a"
|
||||||
, "author": "Mark Nadal"
|
, "author": "Mark Nadal"
|
||||||
, "description": "Graph engine."
|
, "description": "Graph engine."
|
||||||
, "engines": {
|
, "engines": {
|
||||||
|
29
shots.js
29
shots.js
@ -6,6 +6,7 @@
|
|||||||
, meta = {};
|
, meta = {};
|
||||||
Gun.on('opt').event(function(gun, opt){
|
Gun.on('opt').event(function(gun, opt){
|
||||||
gun.server = gun.server || function(req, res, next){ // this whole function needs refactoring and modularization
|
gun.server = gun.server || function(req, res, next){ // this whole function needs refactoring and modularization
|
||||||
|
//console.log("\n\n GUN SERVER!");
|
||||||
next = next || function(){};
|
next = next || function(){};
|
||||||
if(!req || !res){ return next() }
|
if(!req || !res){ return next() }
|
||||||
if(!req.url){ return next() }
|
if(!req.url){ return next() }
|
||||||
@ -66,6 +67,7 @@
|
|||||||
s3.prenode = s3.prenode || opt.s3.prenode || '_/nodes/';
|
s3.prenode = s3.prenode || opt.s3.prenode || '_/nodes/';
|
||||||
gun.__.opt.batch = opt.batch || gun.__.opt.batch || 10;
|
gun.__.opt.batch = opt.batch || gun.__.opt.batch || 10;
|
||||||
gun.__.opt.throttle = opt.throttle || gun.__.opt.throttle || 15;
|
gun.__.opt.throttle = opt.throttle || gun.__.opt.throttle || 15;
|
||||||
|
gun.__.opt.disconnect = opt.disconnect || gun.__.opt.disconnect || 5;
|
||||||
if(!gun.__.opt.keepMaxSockets){ require('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = Infinity } // WARNING: Document this!
|
if(!gun.__.opt.keepMaxSockets){ require('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = Infinity } // WARNING: Document this!
|
||||||
|
|
||||||
s3.load = s3.load || function(key, cb, opt){
|
s3.load = s3.load || function(key, cb, opt){
|
||||||
@ -160,11 +162,12 @@
|
|||||||
|
|
||||||
gun.server.transport = (function(){
|
gun.server.transport = (function(){
|
||||||
function tran(req, cb){
|
function tran(req, cb){
|
||||||
//console.log("\n\n\n", req);
|
//console.log(req);
|
||||||
req.sub = req.headers['gun-sub']; // grab the sub
|
req.sub = req.headers['gun-sub']; // grab the sub
|
||||||
req.tab = tran.sub.s[req.sub] || {}; // check to see if there already is a tab associated with it, or create one
|
req.tab = tran.sub.s[req.sub] || {}; // check to see if there already is a tab associated with it, or create one
|
||||||
req.tab.sub = req.sub = req.sub || Gun.text.random(); // Generate a session id if we don't already have one
|
req.tab.sub = req.sub = req.sub || Gun.text.random(); // Generate a session id if we don't already have one
|
||||||
req.tran = tran.xhr(req, cb) || tran.jsonp(req, cb); // polyfill transport layer
|
req.tran = tran.xhr(req, cb) || tran.jsonp(req, cb); // polyfill transport layer
|
||||||
|
clearTimeout(req.tab.timeout);
|
||||||
// raw test for now, no auth:
|
// raw test for now, no auth:
|
||||||
if(!req.tran){ return cb({headers: {"Content-Type": tran.json}, body: {err: "No transport layer!"}}) }
|
if(!req.tran){ return cb({headers: {"Content-Type": tran.json}, body: {err: "No transport layer!"}}) }
|
||||||
if('post' === req.method || 'patch' === req.method){ return tran.post(req, req.tran) } // TODO: Handle JSONP emulated POST via GET
|
if('post' === req.method || 'patch' === req.method){ return tran.post(req, req.tran) } // TODO: Handle JSONP emulated POST via GET
|
||||||
@ -204,7 +207,7 @@
|
|||||||
if(context.err){ return cb({body: {err: context.err}}) }
|
if(context.err){ return cb({body: {err: context.err}}) }
|
||||||
// WARNING! TODO: BUG! Do not send OK confirmation if amnesiaQuaratine is activated! Not until after it has actually been processed!!!
|
// WARNING! TODO: BUG! Do not send OK confirmation if amnesiaQuaratine is activated! Not until after it has actually been processed!!!
|
||||||
if(Gun.fns.is(gun.__.opt.hooks.set)){
|
if(Gun.fns.is(gun.__.opt.hooks.set)){
|
||||||
gun.__.opt.hooks.set(context.nodes, function(err, data){ // now iterate through those nodes to S3 and get a callback once all are saved
|
gun.__.opt.hooks.set(context.nodes, function saved(err, data){ // now iterate through those nodes to S3 and get a callback once all are saved
|
||||||
var body = {};
|
var body = {};
|
||||||
if(err){
|
if(err){
|
||||||
body.err = err ;
|
body.err = err ;
|
||||||
@ -217,6 +220,7 @@
|
|||||||
}
|
}
|
||||||
var now = tran.post.s[req.sub]; // begin our stupid Chrome fix, we should abstract this out into defer (where it belogns) to keep things clean.
|
var now = tran.post.s[req.sub]; // begin our stupid Chrome fix, we should abstract this out into defer (where it belogns) to keep things clean.
|
||||||
if(!now){ return } // utoh we've lost our reply to the tab!
|
if(!now){ return } // utoh we've lost our reply to the tab!
|
||||||
|
clearTimeout(now.timeout);
|
||||||
now.body = now.body || {}; // make sure we have a body for our multi-response in a single response.
|
now.body = now.body || {}; // make sure we have a body for our multi-response in a single response.
|
||||||
if(req.wait){ // did this request get deferred?
|
if(req.wait){ // did this request get deferred?
|
||||||
(now.body.refed = now.body.refed || {})[req.wait] = err? {err: err} : defer.map({}, context.nodes, 1); // then reply to it "here".
|
(now.body.refed = now.body.refed || {})[req.wait] = err? {err: err} : defer.map({}, context.nodes, 1); // then reply to it "here".
|
||||||
@ -224,7 +228,7 @@
|
|||||||
now.body.reply = err? {err: err} : defer.map({}, context.nodes, 1); // else this is the original POST that had to be upgraded.
|
now.body.reply = err? {err: err} : defer.map({}, context.nodes, 1); // else this is the original POST that had to be upgraded.
|
||||||
}
|
}
|
||||||
if(0 < (now.count = ((now.count || 0) - 1))){ // Don't reply till all deferred POSTs have successfully heard back from S3. (Sarcasm: Like counting guarantees that)
|
if(0 < (now.count = ((now.count || 0) - 1))){ // Don't reply till all deferred POSTs have successfully heard back from S3. (Sarcasm: Like counting guarantees that)
|
||||||
return; // TODO: BUG!!! Memory leak, we have no guarantee we'll ever get a reply! So time it out, maybe some multiple of the S3 throttle.
|
return now.timeout = setTimeout(saved, gun.__.opt.throttle * 2 * 1000); // reply not guaranteed, so time it out, in seconds.
|
||||||
}
|
}
|
||||||
if(Gun.fns.is(now)){
|
if(Gun.fns.is(now)){
|
||||||
now({body: now.body}); // FINALLY reply for ALL the POSTs for that session that accumulated.
|
now({body: now.body}); // FINALLY reply for ALL the POSTs for that session that accumulated.
|
||||||
@ -278,6 +282,7 @@
|
|||||||
//console.log("<-- ", req.sub, req.tran ," -->");
|
//console.log("<-- ", req.sub, req.tran ," -->");
|
||||||
req.tab = tran.sub.s[req.sub];
|
req.tab = tran.sub.s[req.sub];
|
||||||
if(!req.tab){
|
if(!req.tab){
|
||||||
|
console.log(req.url.query);
|
||||||
cb({
|
cb({
|
||||||
headers: {'Gun-Sub': ''}
|
headers: {'Gun-Sub': ''}
|
||||||
,body: {err: "Please re-initialize sub."}
|
,body: {err: "Please re-initialize sub."}
|
||||||
@ -286,6 +291,7 @@
|
|||||||
}
|
}
|
||||||
//console.log("\n\n\n THE CURRENT STATUS IS");console.log(req.tab);
|
//console.log("\n\n\n THE CURRENT STATUS IS");console.log(req.tab);
|
||||||
if(req.tab.queue && req.tab.queue.length){
|
if(req.tab.queue && req.tab.queue.length){
|
||||||
|
tran.clean(req.tab); // We flush their data now, if they don't come back for more within timeout, we remove their session
|
||||||
console.log("_____ NOW PUSHING YOUR DATA ______", req.sub);
|
console.log("_____ NOW PUSHING YOUR DATA ______", req.sub);
|
||||||
cb({ headers: {'Gun-Sub': req.sub} });
|
cb({ headers: {'Gun-Sub': req.sub} });
|
||||||
while(1 < req.tab.queue.length){
|
while(1 < req.tab.queue.length){
|
||||||
@ -299,7 +305,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tran.sub.s = {};
|
tran.sub.s = {};
|
||||||
tran.sub.scribe = function(tab, id){ // TODO: BUG!!! Memory leaks, remember to destroy sessions via timeout.
|
tran.clean = function(tab, mult){
|
||||||
|
if(!tab){ return }
|
||||||
|
mult = mult || 1;
|
||||||
|
clearTimeout(tab.timeout);
|
||||||
|
tab.timeout = setTimeout(function(){
|
||||||
|
if(!tab){ return }
|
||||||
|
if(tab.reply){ tab.reply({body: {err: "Connection timed out"}}) }
|
||||||
|
console.log("!!!! DISCONNECTING CLIENT !!!!!", tab.sub);
|
||||||
|
Gun.obj.del(tran.sub.s, tab.sub)
|
||||||
|
}, gun.__.opt.disconnect * mult * 1000); // in seconds
|
||||||
|
}
|
||||||
|
tran.sub.scribe = function(tab, id){
|
||||||
tran.sub.s[tab.sub] = tab;
|
tran.sub.s[tab.sub] = tab;
|
||||||
tab.subs = tab.subs || {};
|
tab.subs = tab.subs || {};
|
||||||
tab.subs[id] = tab.subs[id] || tran.push.on(id).event(function(req){
|
tab.subs[id] = tab.subs[id] || tran.push.on(id).event(function(req){
|
||||||
@ -307,7 +324,8 @@
|
|||||||
if(!tab){ return this.off() } // resolve any dangling callbacks
|
if(!tab){ return this.off() } // resolve any dangling callbacks
|
||||||
req.sub = req.sub || req.headers['gun-sub'];
|
req.sub = req.sub || req.headers['gun-sub'];
|
||||||
if(req.sub === tab.sub){ return } // do not send back to the tab that sent it
|
if(req.sub === tab.sub){ return } // do not send back to the tab that sent it
|
||||||
console.log('FROM:', req.sub, "TO:", tab);
|
console.log('FROM:', req.sub, "TO:", tab.sub);
|
||||||
|
tran.clean(tab);
|
||||||
if(tab.reply){
|
if(tab.reply){
|
||||||
tab.reply({
|
tab.reply({
|
||||||
headers: {'Gun-Sub': tab.sub}
|
headers: {'Gun-Sub': tab.sub}
|
||||||
@ -318,6 +336,7 @@
|
|||||||
}
|
}
|
||||||
(tab.queue = tab.queue || []).push(req.body);
|
(tab.queue = tab.queue || []).push(req.body);
|
||||||
});
|
});
|
||||||
|
tran.clean(tab, 2);
|
||||||
}
|
}
|
||||||
tran.xhr = function(req, cb){ // Streaming Long Polling
|
tran.xhr = function(req, cb){ // Streaming Long Polling
|
||||||
return req.tran || (req.headers['x-requested-with'] === 'XMLHttpRequest'? transport : null);
|
return req.tran || (req.headers['x-requested-with'] === 'XMLHttpRequest'? transport : null);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user