;(function(){ /* HOW TO USE: 1. On your HTML include gun and this file: 2. Initiate GUN with default WebSocket turned off: var gun = Gun({WebSocket: false}); */ var WebSocket; if(typeof window !== 'undefined'){ WebSocket = window.WebSocket || window.webkitWebSocket || window.mozWebSocket; } else { return; } Gun.on('opt', function(ctx){ this.to.next(ctx); var opt = ctx.opt; if(ctx.once){ return } opt.wsc = opt.wsc || {protocols:[]}; // for d3x0r! var ws = opt.ws || (opt.ws = {}); ws.who = 0; Gun.obj.map(opt.peers, function(){ ++ws.who }); if(ctx.once){ return } var batch; ctx.on('out', function(at){ this.to.next(at); if(at.ws && 1 == ws.who){ return } // performance hack for reducing echoes. batch = JSON.stringify(at); if(ws.drain){ ws.drain.push(batch); return; } ws.drain = []; setTimeout(function(){ if(!ws.drain){ return } var tmp = ws.drain; ws.drain = null; if(!tmp.length){ return } batch = JSON.stringify(tmp); Gun.obj.map(opt.peers, send, ctx); }, opt.wait || 1); Gun.obj.map(opt.peers, send, ctx); }); function send(peer){ var ctx = this, msg = batch; var wire = peer.wire || open(peer, ctx); if(!wire){ return } if(wire.readyState === wire.OPEN){ wire.send(msg); return; } (peer.queue = peer.queue || []).push(msg); } function receive(msg, peer, ctx){ if(!ctx || !msg){ return } try{msg = JSON.parse(msg.data || msg); }catch(e){} if(msg instanceof Array){ var i = 0, m; while(m = msg[i++]){ receive(m, peer, ctx); } return; } if(1 == ws.who){ msg.ws = noop } // If there is only 1 client, just use noop since it doesn't matter. ctx.on('in', msg); } function open(peer, as){ if(!peer || !peer.url){ return } var url = peer.url.replace('http', 'ws'); var wire = peer.wire = new WebSocket(url, as.opt.wsc.protocols, as.opt.wsc); wire.onclose = function(){ reconnect(peer, as); }; wire.onerror = function(error){ reconnect(peer, as); // placement? if(!error){ return } if(error.code === 'ECONNREFUSED'){ //reconnect(peer, as); } }; wire.onopen = function(){ var queue = peer.queue; peer.queue = []; Gun.obj.map(queue, function(msg){ batch = msg; send.call(as, peer); }); } wire.onmessage = function(msg){ receive(msg, peer, as); // diff: peer not wire! }; return wire; } function reconnect(peer, as){ clearTimeout(peer.defer); peer.defer = setTimeout(function(){ open(peer, as); }, 2 * 1000); } }); var noop = function(){}; }());