mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
Add envelope-system server sync
Using gun's new envelope system (where routing and de-duplication happen inside gun core), server-to-server synchronization has been implemented. However, it comes with this warning: the chain isn't yet ready and you'll have difficulty reading or writing data via the chain.
This commit is contained in:
parent
9d9dea2553
commit
4848493530
39
gun.js
39
gun.js
@ -1,4 +1,5 @@
|
||||
/* eslint-disable */
|
||||
/* eslint-enable no-console */
|
||||
//console.log("!!!!!!!!!!!!!!!! WARNING THIS IS GUN 0.5 !!!!!!!!!!!!!!!!!!!!!!");
|
||||
;(function(){
|
||||
|
||||
@ -929,21 +930,26 @@
|
||||
gun.on('in', input, at);
|
||||
gun.on('out', output, at);
|
||||
}
|
||||
function output(at){
|
||||
var cat = this, gun = cat.gun, tmp;
|
||||
console.log("OUT!", Gun.obj.to(at, {gun: null}));
|
||||
if(at['#']){
|
||||
dedup.track(at['#']);
|
||||
function output(at){
|
||||
var cat = this, gun = cat.gun, tmp;
|
||||
if(at['#']){
|
||||
dedup.track(at['#']);
|
||||
}
|
||||
if(at.put){
|
||||
if(at.put){
|
||||
cat.on('in', obj_to(at, {gun: cat.gun}));
|
||||
}
|
||||
if(!at.gun){
|
||||
at = Gun.obj.to(at, {gun: gun});
|
||||
}
|
||||
if(at.put){ Gun.on('put', at) }
|
||||
if(at.get){ get(at, cat) }
|
||||
Gun.on('out', at); return;
|
||||
if(at.put){ Gun.on('put', at) }
|
||||
if(at.get){ get(at, cat) }
|
||||
|
||||
// Reads and writes both trigger output.
|
||||
if (at.put !== undefined || at.get !== undefined) {
|
||||
Gun.on('out', at);
|
||||
}
|
||||
// Gun.on('out', at);
|
||||
return;
|
||||
if(!cat.back){ return }
|
||||
cat.back.on('out', at);
|
||||
}
|
||||
@ -963,8 +969,7 @@
|
||||
Gun.on('get', at);
|
||||
}
|
||||
function input(at){ var cat = this;
|
||||
console.log("IN", at);
|
||||
if(at['@']){
|
||||
if(at['@']){
|
||||
if(!at['#']){
|
||||
at['#'] = Gun.text.random();
|
||||
dedup.track(at['#']);
|
||||
@ -979,15 +984,15 @@
|
||||
return;
|
||||
}
|
||||
*/
|
||||
if(at.put){
|
||||
if(!at.gun){ at.gun = cat.gun }
|
||||
if(at.put){
|
||||
if(cat.graph){
|
||||
Gun.obj.map(at.put, ham, {at: at, cat: this}); // all unions must happen first, sadly.
|
||||
}
|
||||
Gun.obj.map(at.put, map, {at: at, cat: this});
|
||||
Gun.on('put', at);
|
||||
}
|
||||
if(!at.gun){ at.gun = cat.gun }
|
||||
if(at.get){ Gun.on('get', at) }
|
||||
if(at.get){ Gun.on('get', at) }
|
||||
}
|
||||
function ham(data, key){
|
||||
var cat = this.cat, graph = cat.graph;
|
||||
@ -2182,8 +2187,7 @@
|
||||
}
|
||||
if(!ws.readyState){ return setTimeout(function(){ r.ws(opt, cb, req) },100), true }
|
||||
ws.sending = true;
|
||||
console.log("websocket out", req);
|
||||
ws.send(JSON.stringify(req));
|
||||
ws.send(JSON.stringify(req));
|
||||
return true;
|
||||
}
|
||||
if(ws === false){ return }
|
||||
@ -2382,8 +2386,7 @@
|
||||
Tab.peers.request.createServer(function(req, res){
|
||||
if(!req || !res || !req.body || !req.headers){ return }
|
||||
var msg = req.body;
|
||||
console.log("SERVER", req);
|
||||
gun.on('in', req.body);
|
||||
gun.on('in', req.body);
|
||||
return;
|
||||
// AUTH for non-replies.
|
||||
if(server.msg(msg['#'])){ return }
|
||||
|
@ -8,27 +8,11 @@
|
||||
var Gun = require('../../gun');
|
||||
var Socket = require('./Peer');
|
||||
var Pool = require('./Pool');
|
||||
var duplicate = require('./duplicate');
|
||||
|
||||
// Maps URLs to sockets.
|
||||
// Shared between all gun instances.
|
||||
var sockets = Pool();
|
||||
var emitter = { on: Gun.on };
|
||||
var server = {
|
||||
|
||||
// Session id.
|
||||
sid: Gun.text.random(),
|
||||
|
||||
// Request handlers.
|
||||
handlers: [],
|
||||
|
||||
// Call handlers.
|
||||
handle: function (req, res) {
|
||||
server.handlers.forEach(function (server) {
|
||||
server(req, res);
|
||||
});
|
||||
},
|
||||
};
|
||||
var sid = Gun.text.random();
|
||||
|
||||
/**
|
||||
* Take a map of URLs pointing to options and ensure the
|
||||
@ -61,108 +45,20 @@ function getSocketSubset (peers) {
|
||||
});
|
||||
}
|
||||
|
||||
// Handle read requests.
|
||||
Gun.on('get', function (at) {
|
||||
var gun = at.gun;
|
||||
var opt = at.opt || {};
|
||||
Gun.on('out', function (ctx) {
|
||||
var gun = ctx.gun;
|
||||
var opt = ctx.opt || {};
|
||||
var peers = opt.peers || gun.Back('opt.peers');
|
||||
|
||||
if (!peers || Gun.obj.empty(peers)) {
|
||||
at.gun.Back(Infinity).on('in', {
|
||||
'@': at['#'],
|
||||
});
|
||||
|
||||
if (!peers) {
|
||||
return;
|
||||
}
|
||||
|
||||
var id = at['#'] || Gun.text.random(9);
|
||||
|
||||
// Create a new message.
|
||||
var msg = {
|
||||
|
||||
// msg ID
|
||||
'#': id,
|
||||
|
||||
// msg BODY
|
||||
'$': at.get,
|
||||
};
|
||||
|
||||
// Listen for a response.
|
||||
// TODO: ONE? PERF! Clear out listeners, maybe with setTimeout?
|
||||
emitter.on(id, function (err, data) {
|
||||
var obj = {
|
||||
'@': at['#'],
|
||||
err: err,
|
||||
put: data,
|
||||
};
|
||||
|
||||
if (data) {
|
||||
at.gun.Back(-1).on('out', obj);
|
||||
} else {
|
||||
at.gun.Back(-1).on('in', obj);
|
||||
}
|
||||
});
|
||||
|
||||
var subset = getSocketSubset(peers);
|
||||
|
||||
// Broadcast to the connected peers.
|
||||
subset.send({
|
||||
headers: { 'gun-sid': server.sid },
|
||||
body: msg,
|
||||
});
|
||||
});
|
||||
|
||||
// Handle write requests.
|
||||
Gun.on('put', function (at) {
|
||||
if (at['@']) {
|
||||
return;
|
||||
}
|
||||
|
||||
var peers = at.gun.Back('opt.peers');
|
||||
var enabled = at.gun.Back('opt.websocket');
|
||||
var options = at.opt || {};
|
||||
|
||||
if (!peers || Gun.obj.empty(peers)) {
|
||||
|
||||
// TODO: What about wsp/server clients? Maybe we shouldn't
|
||||
// immediately assume there's no data to be found.
|
||||
at.gun.Back(-1).on('in', {
|
||||
'@': at['#'],
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.websocket === false || enabled === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
var id = at['#'] || Gun.text.random(9);
|
||||
|
||||
var msg = {
|
||||
|
||||
// Message ID.
|
||||
'#': id,
|
||||
|
||||
// Message body.
|
||||
'$': at.put,
|
||||
};
|
||||
|
||||
// TODO: ONE? PERF! Clear out listeners, maybe with setTimeout?
|
||||
// Listen for acknowledgement(s).
|
||||
Gun.on(id, function (err, ok) {
|
||||
at.gun.Back(-1).on('in', {
|
||||
'@': at['#'],
|
||||
err: err,
|
||||
ok: ok,
|
||||
});
|
||||
});
|
||||
|
||||
var subset = getSocketSubset(peers);
|
||||
|
||||
subset.send({
|
||||
headers: { 'gun-sid': server.sid },
|
||||
body: msg,
|
||||
headers: { 'gun-sid': sid },
|
||||
body: ctx,
|
||||
});
|
||||
});
|
||||
|
||||
@ -170,6 +66,7 @@ Gun.on('put', function (at) {
|
||||
// adding them to the global pool.
|
||||
Gun.on('opt', function (context) {
|
||||
var gun = context.gun;
|
||||
var root = gun.Back(Infinity);
|
||||
|
||||
var peers = gun.Back('opt.peers') || {};
|
||||
|
||||
@ -181,22 +78,6 @@ Gun.on('opt', function (context) {
|
||||
var socket = Socket(url, options);
|
||||
sockets.add(url, socket);
|
||||
|
||||
/**
|
||||
* Handle responses to requests, adding default headers.
|
||||
* @param {Object} reply - A gun reply object.
|
||||
* @return {undefined}
|
||||
*/
|
||||
function respond (reply) {
|
||||
|
||||
// Make sure headers are defined.
|
||||
var headers = reply.headers = reply.headers || {};
|
||||
|
||||
// Add 'gun-sid' if it doesn't exist.
|
||||
headers['gun-sid'] = headers['gun-sid'] || server.sid;
|
||||
|
||||
socket.send(reply);
|
||||
}
|
||||
|
||||
socket.on('message', function (msg) {
|
||||
var request;
|
||||
|
||||
@ -211,132 +92,7 @@ Gun.on('opt', function (context) {
|
||||
return;
|
||||
}
|
||||
|
||||
request.headers = request.headers || {};
|
||||
|
||||
// emit extra events.
|
||||
server.handle(request, respond);
|
||||
root.on('in', request.body);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Gun.on('opt', function (at) {
|
||||
var gun = at.gun;
|
||||
var root = gun.Back(Infinity);
|
||||
var options = (root._.opt = root._.opt || {});
|
||||
|
||||
// Only register once per gun instance.
|
||||
if (options['@client']) {
|
||||
return;
|
||||
}
|
||||
|
||||
var driver = options['@client'] = {
|
||||
|
||||
/**
|
||||
* Handles get requests sent from other peers.
|
||||
* @param {Object} req - The get request.
|
||||
* @param {Function} cb - Handles replies.
|
||||
* @return {undefined}
|
||||
*/
|
||||
get: function (req, cb) {
|
||||
var body = req.body;
|
||||
var lex = body.$;
|
||||
var graph = gun._.root._.graph;
|
||||
var node = graph[lex['#']];
|
||||
|
||||
// TODO: Reply even if it's not in memory.
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
cb({
|
||||
body: {
|
||||
'#': duplicate.track.newID(),
|
||||
'@': body['#'],
|
||||
'$': node,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles put requests sent from other peers.
|
||||
* @param {Object} req - The put request.
|
||||
* @param {Function} cb - A response callback.
|
||||
* @return {undefined}
|
||||
*/
|
||||
put: function (req, cb) {
|
||||
var body = req.body;
|
||||
var graph = body.$;
|
||||
|
||||
// Cached gun paths.
|
||||
var path = gun._.root._.path || {};
|
||||
|
||||
graph = Gun.obj.map(graph, function (node, soul, map) {
|
||||
if (!path[soul]) {
|
||||
return;
|
||||
}
|
||||
map(soul, node);
|
||||
});
|
||||
|
||||
// filter out what we don't have in memory.
|
||||
if (!graph) {
|
||||
return;
|
||||
}
|
||||
|
||||
var id = Gun.on.ask(function (ack, event) {
|
||||
if (!ack) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.off();
|
||||
|
||||
cb({
|
||||
body: {
|
||||
'#': duplicate.track.newID(),
|
||||
'@': body['#'],
|
||||
'$': ack,
|
||||
'!': ack.err,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
gun.on('out', {
|
||||
'#': duplicate.track(id),
|
||||
gun: gun,
|
||||
opt: { websocket: false },
|
||||
put: graph,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
server.handlers.push(function (req, res) {
|
||||
|
||||
// Validate request.
|
||||
if (!req || !res || !req.body || !req.headers) {
|
||||
return;
|
||||
}
|
||||
|
||||
var msg = req.body;
|
||||
|
||||
if (duplicate(msg['#'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// It's a response, no need to reply.
|
||||
if (msg['@']) {
|
||||
var reqID = msg['@'];
|
||||
|
||||
emitter.on(reqID, [
|
||||
msg['!'],
|
||||
msg.$,
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var isLex = msg.$ && msg.$['#'];
|
||||
var method = isLex ? 'get' : 'put';
|
||||
|
||||
driver[method](req, res);
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -38,68 +38,20 @@ function ready (socket, cb) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request to a list of clients.
|
||||
* @param {Obejct} context - A gun request context.
|
||||
* Send a message to a group of clients.
|
||||
* @param {Obejct} msg - An http envelope-like message.
|
||||
* @param {Object} clients - IDs mapped to socket instances.
|
||||
* @param {Function} cb - Called for each response.
|
||||
* @return {undefined}
|
||||
*/
|
||||
function request (context, clients, cb) {
|
||||
var id = context['#'] || Gun.text.random(9);
|
||||
|
||||
Gun.on(id, function (err, data, event) {
|
||||
cb(err, data);
|
||||
event.off();
|
||||
});
|
||||
|
||||
function send (msg, clients) {
|
||||
Gun.obj.map(clients, function (client) {
|
||||
ready(client, function () {
|
||||
var msg = {
|
||||
headers: {},
|
||||
body: {
|
||||
'#': id,
|
||||
'$': context.get,
|
||||
},
|
||||
};
|
||||
|
||||
var serialized = JSON.stringify(msg);
|
||||
client.send(serialized);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes a graph update to a collection of clients.
|
||||
* @param {Object} context - The context object passed by gun.
|
||||
* @param {Object} clients - An object mapping URLs to clients.
|
||||
* @param {Function} cb - Invoked on each client response.
|
||||
* @return {undefined}
|
||||
*/
|
||||
function update (context, clients, cb) {
|
||||
var id = context['#'] || Gun.text.random(9);
|
||||
|
||||
Gun.on(id, function (err, data, event) {
|
||||
cb(err, data);
|
||||
event.off();
|
||||
});
|
||||
|
||||
Gun.obj.map(clients, function (client) {
|
||||
ready(client, function () {
|
||||
var msg = {
|
||||
headers: {},
|
||||
body: {
|
||||
'#': id,
|
||||
'$': context.put,
|
||||
},
|
||||
};
|
||||
|
||||
var serialized = JSON.stringify(msg);
|
||||
|
||||
client.send(serialized);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** * Attaches server push middleware to gun.
|
||||
* @param {Gun} gun - The gun instance to attach to.
|
||||
* @param {WebSocket.Server} server - A websocket server instance.
|
||||
@ -110,6 +62,7 @@ function attach (gun, server) {
|
||||
root._.servers = root._.servers || [];
|
||||
root._.servers.push(server);
|
||||
var pool = {};
|
||||
var sid = Gun.text.random();
|
||||
|
||||
server.on('connection', function (socket) {
|
||||
socket.id = socket.id || Gun.text.random(10);
|
||||
@ -122,12 +75,7 @@ function attach (gun, server) {
|
||||
return;
|
||||
}
|
||||
|
||||
var msg = data.body;
|
||||
|
||||
if (msg['@']) {
|
||||
Gun.on.ack(msg['@'], [msg['!'], msg.$]);
|
||||
return;
|
||||
}
|
||||
root.on('in', data.body);
|
||||
});
|
||||
|
||||
socket.once('close', function () {
|
||||
@ -135,40 +83,17 @@ function attach (gun, server) {
|
||||
});
|
||||
});
|
||||
|
||||
Gun.on('get', function (context) {
|
||||
if (!isUsingServer(context.gun, server)) {
|
||||
Gun.on('out', function (context) {
|
||||
if (!isUsingServer(context.gun, server) || Gun.obj.empty(pool)) {
|
||||
return;
|
||||
}
|
||||
|
||||
request(context, pool, function (err, data) {
|
||||
var response = {
|
||||
'@': context['#'],
|
||||
put: data,
|
||||
err: err,
|
||||
};
|
||||
var msg = {
|
||||
headers: { 'gun-sid': sid },
|
||||
body: context,
|
||||
};
|
||||
|
||||
var root = context.gun.Back(Infinity);
|
||||
|
||||
root.on(data ? 'out' : 'in', response);
|
||||
});
|
||||
});
|
||||
|
||||
Gun.on('put', function (context) {
|
||||
if (!isUsingServer(context.gun, server)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.nopush) {
|
||||
return;
|
||||
}
|
||||
|
||||
update(context, pool, function (err, data) {
|
||||
var ack = {
|
||||
'!': err || null,
|
||||
'$': data.$,
|
||||
};
|
||||
Gun.on.ack(context, ack);
|
||||
});
|
||||
send(msg, pool);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,22 +1,24 @@
|
||||
var Gun = require('../../gun')
|
||||
, formidable = require('formidable')
|
||||
, http = require('../http')
|
||||
, url = require('url')
|
||||
, wsp = {}
|
||||
, WS = require('ws')
|
||||
, WSS = WS.Server
|
||||
, attach = require('./server-push');
|
||||
/* eslint-disable require-jsdoc, no-underscore-dangle */
|
||||
'use strict';
|
||||
var Gun = require('../../gun');
|
||||
var http = require('../http');
|
||||
var url = require('url');
|
||||
var WS = require('ws');
|
||||
var WSS = WS.Server;
|
||||
var attach = require('./server-push');
|
||||
|
||||
// Handles server to server sync.
|
||||
require('./client.js');
|
||||
|
||||
Gun.on('opt', function(at){
|
||||
Gun.on('opt', function (at) {
|
||||
var gun = at.gun, opt = at.opt;
|
||||
gun.__ = at.root._;
|
||||
gun.__.opt.ws = opt.ws = gun.__.opt.ws || opt.ws || {};
|
||||
|
||||
function start(server, port, app){
|
||||
if(app && app.use){ app.use(gun.wsp.server) }
|
||||
function start (server, port, app) {
|
||||
if (app && app.use) {
|
||||
app.use(gun.wsp.server);
|
||||
}
|
||||
server = gun.__.opt.ws.server = gun.__.opt.ws.server || opt.ws.server || server;
|
||||
|
||||
if (!gun.wsp.ws) {
|
||||
@ -25,141 +27,155 @@ Gun.on('opt', function(at){
|
||||
}
|
||||
|
||||
gun.wsp.ws = gun.wsp.ws || new WSS(gun.__.opt.ws);
|
||||
require('./ws')(gun.wsp.ws, function(req, res){
|
||||
require('./ws')(gun.wsp.ws, function (req, res) {
|
||||
var ws = this;
|
||||
req.headers['gun-sid'] = ws.sid = ws.sid? ws.sid : req.headers['gun-sid'];
|
||||
ws.sub = ws.sub || gun.wsp.on('network', function(msg, ev){
|
||||
if(!ws || !ws.send || !ws._socket || !ws._socket.writable){ return ev.off() }
|
||||
if(!msg || (msg.headers && msg.headers['gun-sid'] === ws.sid)){ return }
|
||||
if(msg && msg.headers){ delete msg.headers['ws-rid'] }
|
||||
req.headers['gun-sid'] = ws.sid = ws.sid ? ws.sid : req.headers['gun-sid'];
|
||||
ws.sub = ws.sub || gun.wsp.on('network', function (msg, ev) {
|
||||
if (!ws || !ws.send || !ws._socket || !ws._socket.writable) { return ev.off(); }
|
||||
if (!msg || (msg.headers && msg.headers['gun-sid'] === ws.sid)) { return; }
|
||||
if (msg && msg.headers) { delete msg.headers['ws-rid']; }
|
||||
// TODO: BUG? ^ What if other peers want to ack? Do they use the ws-rid or a gun declared id?
|
||||
try{ws.send(Gun.text.ify(msg));
|
||||
}catch(e){} // juuuust in case.
|
||||
try { ws.send(Gun.text.ify(msg));
|
||||
} catch (e) {} // juuuust in case.
|
||||
});
|
||||
gun.wsp.wire(req, res);
|
||||
}, {headers: {'ws-rid': 1, 'gun-sid': 1}});
|
||||
gun.__.opt.ws.port = gun.__.opt.ws.port || opt.ws.port || port || 80;
|
||||
}
|
||||
var wsp = gun.wsp = gun.wsp || function(server){
|
||||
if(!server){ return gun }
|
||||
if(Gun.fns.is(server.address)){
|
||||
if(server.address()){
|
||||
var wsp = gun.wsp = gun.wsp || function (server) {
|
||||
if (!server) { return gun; }
|
||||
if (Gun.fns.is(server.address)) {
|
||||
if (server.address()) {
|
||||
start(server, server.address().port);
|
||||
return gun;
|
||||
}
|
||||
}
|
||||
if(Gun.fns.is(server.get) && server.get('port')){
|
||||
if (Gun.fns.is(server.get) && server.get('port')) {
|
||||
start(server, server.get('port'));
|
||||
return gun;
|
||||
}
|
||||
var listen = server.listen;
|
||||
server.listen = function(port){
|
||||
server.listen = function (port) {
|
||||
var serve = listen.apply(server, arguments);
|
||||
start(serve, port, server);
|
||||
return serve;
|
||||
}
|
||||
};
|
||||
return gun;
|
||||
}
|
||||
};
|
||||
gun.wsp.on = gun.wsp.on || Gun.on;
|
||||
gun.wsp.regex = gun.wsp.regex || opt.route || opt.path || /^\/gun/i;
|
||||
gun.wsp.poll = gun.wsp.poll || opt.poll || 1;
|
||||
gun.wsp.pull = gun.wsp.pull || opt.pull || gun.wsp.poll * 1000;
|
||||
gun.wsp.server = gun.wsp.server || function(req, res, next){ // http
|
||||
next = next || function(){};
|
||||
if(!req || !res){ return next(), false }
|
||||
if(!req.url){ return next(), false }
|
||||
if(!req.method){ return next(), false }
|
||||
gun.wsp.server = gun.wsp.server || function (req, res, next) { // http
|
||||
next = next || function () {};
|
||||
if (!req || !res) { return next(), false; }
|
||||
if (!req.url) { return next(), false; }
|
||||
if (!req.method) { return next(), false; }
|
||||
var msg = {};
|
||||
msg.url = url.parse(req.url, true);
|
||||
if(!gun.wsp.regex.test(msg.url.pathname)){ return next(), false } // TODO: BUG! If the option isn't a regex then this will fail!
|
||||
if(msg.url.pathname.replace(gun.wsp.regex,'').slice(0,3).toLowerCase() === '.js'){
|
||||
if (!gun.wsp.regex.test(msg.url.pathname)) { return next(), false; } // TODO: BUG! If the option isn't a regex then this will fail!
|
||||
if (msg.url.pathname.replace(gun.wsp.regex, '').slice(0, 3).toLowerCase() === '.js') {
|
||||
res.writeHead(200, {'Content-Type': 'text/javascript'});
|
||||
res.end(gun.wsp.js = gun.wsp.js || require('fs').readFileSync(__dirname + '/../../gun.js')); // gun server is caching the gun library for the client
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!req.upgrade){
|
||||
if (!req.upgrade) {
|
||||
next();
|
||||
return false;
|
||||
}
|
||||
|
||||
return http(req, res, function(req, res){
|
||||
if(!req){ return next() }
|
||||
return http(req, res, function (req, res) {
|
||||
if (!req) { return next(); }
|
||||
var stream, cb = res = require('../jsonp')(req, res);
|
||||
if(req.headers && (stream = req.headers['gun-sid'])){
|
||||
if (req.headers && (stream = req.headers['gun-sid'])) {
|
||||
stream = (gun.wsp.peers = gun.wsp.peers || {})[stream] = gun.wsp.peers[stream] || {sid: stream};
|
||||
stream.drain = stream.drain || function(res){
|
||||
if(!res || !stream || !stream.queue || !stream.queue.length){ return }
|
||||
stream.drain = stream.drain || function (res) {
|
||||
if (!res || !stream || !stream.queue || !stream.queue.length) { return; }
|
||||
res({headers: {'gun-sid': stream.sid}, body: stream.queue });
|
||||
stream.off = setTimeout(function(){ stream = null }, gun.wsp.pull);
|
||||
stream.off = setTimeout(function () { stream = null; }, gun.wsp.pull);
|
||||
stream.reply = stream.queue = null;
|
||||
return true;
|
||||
}
|
||||
stream.sub = stream.sub || gun.wsp.on('network', function(req, ev){
|
||||
if(!stream){ return ev.off() } // self cleans up after itself!
|
||||
if(!req || (req.headers && req.headers['gun-sid'] === stream.sid)){ return }
|
||||
};
|
||||
stream.sub = stream.sub || gun.wsp.on('network', function (req, ev) {
|
||||
if (!stream) { return ev.off(); } // self cleans up after itself!
|
||||
if (!req || (req.headers && req.headers['gun-sid'] === stream.sid)) { return; }
|
||||
(stream.queue = stream.queue || []).push(req);
|
||||
stream.drain(stream.reply);
|
||||
});
|
||||
cb = function(r){ (r.headers||{}).poll = gun.wsp.poll; res(r) }
|
||||
cb = function (r) { (r.headers || {}).poll = gun.wsp.poll; res(r); };
|
||||
clearTimeout(stream.off);
|
||||
if(req.headers.pull){
|
||||
if(stream.drain(cb)){ return }
|
||||
if (req.headers.pull) {
|
||||
if (stream.drain(cb)) { return; }
|
||||
return stream.reply = cb;
|
||||
}
|
||||
}
|
||||
gun.wsp.wire(req, cb);
|
||||
}), true;
|
||||
}
|
||||
if((gun.__.opt.maxSockets = opt.maxSockets || gun.__.opt.maxSockets) !== false){
|
||||
};
|
||||
if ((gun.__.opt.maxSockets = opt.maxSockets || gun.__.opt.maxSockets) !== false) {
|
||||
require('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = gun.__.opt.maxSockets || Infinity;
|
||||
}
|
||||
gun.wsp.msg = gun.wsp.msg || function(id){
|
||||
if(!id){
|
||||
gun.wsp.msg = gun.wsp.msg || function (id) {
|
||||
if (!id) {
|
||||
return gun.wsp.msg.debounce[id = Gun.text.random(9)] = Gun.time.is(), id;
|
||||
}
|
||||
clearTimeout(gun.wsp.msg.clear);
|
||||
gun.wsp.msg.clear = setTimeout(function(){
|
||||
gun.wsp.msg.clear = setTimeout(function () {
|
||||
var now = Gun.time.is();
|
||||
Gun.obj.map(gun.wsp.msg.debounce, function(t,id){
|
||||
if((now - t) < (1000 * 60 * 5)){ return }
|
||||
Gun.obj.map(gun.wsp.msg.debounce, function (t, id) {
|
||||
if ((now - t) < (1000 * 60 * 5)) { return; }
|
||||
Gun.obj.del(gun.wsp.msg.debounce, id);
|
||||
});
|
||||
},500);
|
||||
if(id = gun.wsp.msg.debounce[id]){
|
||||
}, 500);
|
||||
if (id = gun.wsp.msg.debounce[id]) {
|
||||
return gun.wsp.msg.debounce[id] = Gun.time.is(), id;
|
||||
}
|
||||
gun.wsp.msg.debounce[id] = Gun.time.is();
|
||||
return;
|
||||
};
|
||||
gun.wsp.msg.debounce = gun.wsp.msg.debounce || {};
|
||||
gun.wsp.wire = gun.wsp.wire || (function(){
|
||||
// all streams, technically PATCH but implemented as PUT or POST, are forwarded to other trusted peers
|
||||
// except for the ones that are listed in the message as having already been sending to.
|
||||
// all states, implemented with GET, are replied to the source that asked for it.
|
||||
function tran(req, res){
|
||||
if(!req || !res || !req.body || !req.headers){ return }
|
||||
if(req.url){ req.url = url.format(req.url) }
|
||||
var msg = req.body;
|
||||
// AUTH for non-replies.
|
||||
if(gun.wsp.msg(msg['#'])){ return }
|
||||
gun.wsp.on('network', Gun.obj.copy(req));
|
||||
if(msg['@']){ return } // no need to process.
|
||||
if(msg['$'] && msg['$']['#']){ return tran.get(req, res) }
|
||||
//if(Gun.is.lex(msg['$'])){ return tran.get(req, res) }
|
||||
else { return tran.put(req, res) }
|
||||
cb({body: {hello: 'world'}});
|
||||
// TODO: BUG! server put should push.
|
||||
gun.wsp.wire = gun.wsp.wire || (function () {
|
||||
// all streams, technically PATCH but implemented as
|
||||
// PUT or POST, are forwarded to other trusted peers
|
||||
// except for the ones that are listed in the message
|
||||
// as having already been sent to.
|
||||
// all states, implemented with GET, are replied to the
|
||||
// source that asked for it.
|
||||
function tran (req, res) {
|
||||
if (!req || !res || !req.body || !req.headers) {
|
||||
return;
|
||||
}
|
||||
if (req.url) {
|
||||
req.url = url.format(req.url);
|
||||
}
|
||||
// var msg = req.body;
|
||||
// console.log('SERVER', req);
|
||||
gun.on('in', req.body);
|
||||
// console.log('-----------------');
|
||||
// // AUTH for non-replies.
|
||||
// if(gun.wsp.msg(msg['#'])){ return }
|
||||
// gun.wsp.on('network', Gun.obj.copy(req));
|
||||
// if(msg['@']){ return } // no need to process.
|
||||
// if(msg['$'] && msg['$']['#']){ return tran.get(req, res) }
|
||||
// //if(Gun.is.lex(msg['$'])){ return tran.get(req, res) }
|
||||
// else { return tran.put(req, res) }
|
||||
// cb({body: {hello: 'world'}});
|
||||
// // TODO: BUG! server put should push.
|
||||
}
|
||||
tran.get = function(req, cb){
|
||||
var body = req.body, lex = body['$'], reply = {headers: {'Content-Type': tran.json}};
|
||||
tran.get = function (req, cb) {
|
||||
var body = req.body;
|
||||
var lex = body.$;
|
||||
var reply = {
|
||||
headers: { 'Content-Type': tran.json },
|
||||
};
|
||||
|
||||
var graph = gun.Back(Infinity)._.graph;
|
||||
var node = graph[lex['#']];
|
||||
var result = Gun.graph.ify(node);
|
||||
|
||||
if (node) {
|
||||
return cb({
|
||||
cb({
|
||||
headers: reply.headers,
|
||||
body: {
|
||||
'#': gun.wsp.msg(),
|
||||
@ -167,41 +183,64 @@ Gun.on('opt', function(at){
|
||||
'$': result,
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
gun.on('out', {gun: gun, get: lex, req: 1, '#': body['#'] || Gun.on.ask(function(at, ev){
|
||||
ev.off();
|
||||
var graph = at.put;
|
||||
return cb({headers: reply.headers, body: {
|
||||
'#': gun.wsp.msg(),
|
||||
'@': body['#'],
|
||||
'$': graph,
|
||||
'!': at.err
|
||||
}});
|
||||
})});
|
||||
}
|
||||
tran.put = function(req, cb){
|
||||
// NOTE: It is highly recommended you do your own PUT/POSTs through your own API that then saves to gun manually.
|
||||
// This will give you much more fine-grain control over security, transactions, and what not.
|
||||
var body = req.body, graph = body['$'], reply = {headers: {'Content-Type': tran.json}}, opt;
|
||||
gun.on('out', {gun: gun, put: graph, '#': Gun.on.ask(function(ack, ev){
|
||||
//Gun.on('put', {gun: gun, put: graph, '#': Gun.on.ask(function(ack, ev){
|
||||
ev.off();
|
||||
return cb({headers: reply.headers, body: {
|
||||
'#': gun.wsp.msg(),
|
||||
'@': body['#'],
|
||||
'$': ack,
|
||||
'!': ack.err
|
||||
}});
|
||||
})});
|
||||
}
|
||||
gun.wsp.on('network', function(rq){
|
||||
// TODO: MARK! You should move the networking events to here, not in WSS only.
|
||||
});
|
||||
gun.on('out', {
|
||||
gun: gun,
|
||||
get: lex,
|
||||
req: 1,
|
||||
'#': body['#'] || Gun.on.ask(function (at, ev) {
|
||||
ev.off();
|
||||
var graph = at.put;
|
||||
return cb({
|
||||
headers: reply.headers,
|
||||
body: {
|
||||
'#': gun.wsp.msg(),
|
||||
'@': body['#'],
|
||||
'$': graph,
|
||||
'!': at.err,
|
||||
},
|
||||
});
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
tran.put = function (req, cb) {
|
||||
// NOTE: It is highly recommended you do your own PUT/POSTs
|
||||
// through your own API that then saves to gun manually.
|
||||
// This will give you much more fine-grain control over
|
||||
// security, transactions, and what not.
|
||||
var body = req.body;
|
||||
var graph = body.$;
|
||||
var reply = {
|
||||
headers: { 'Content-Type': tran.json },
|
||||
};
|
||||
|
||||
gun.on('out', {
|
||||
gun: gun,
|
||||
put: graph,
|
||||
'#': Gun.on.ask(function (ack, ev) {
|
||||
ev.off();
|
||||
return cb({
|
||||
headers: reply.headers,
|
||||
body: {
|
||||
'#': gun.wsp.msg(),
|
||||
'@': body['#'],
|
||||
'$': ack,
|
||||
'!': ack.err,
|
||||
},
|
||||
});
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
tran.json = 'application/json';
|
||||
return tran;
|
||||
}());
|
||||
if(opt.server){
|
||||
|
||||
if (opt.server) {
|
||||
wsp(opt.server);
|
||||
}
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user