mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
92 lines
3.0 KiB
JavaScript
92 lines
3.0 KiB
JavaScript
var Gun = (typeof window !== "undefined")? window.Gun : require('../gun');
|
|
|
|
Gun.on('create', function(root){
|
|
this.to.next(root);
|
|
var opt = root.opt;
|
|
if(false === opt.multicast){ return }
|
|
if((typeof process !== "undefined") && 'false' === ''+(process.env||{}).MULTICAST){ return }
|
|
//if(true !== opt.multicast){ return } // disable multicast by default for now.
|
|
|
|
var udp = opt.multicast = opt.multicast || {};
|
|
udp.address = udp.address || '233.255.255.255';
|
|
udp.pack = udp.pack || 50000; // UDP messages limited to 65KB.
|
|
udp.port = udp.port || 8765;
|
|
|
|
var noop = function(){}, u;
|
|
var pid = '2'+Math.random().toString().slice(-8);
|
|
var mesh = opt.mesh = opt.mesh || Gun.Mesh(root);
|
|
var dgram;
|
|
|
|
try{ dgram = require("dgram") }catch(e){ return }
|
|
var socket = dgram.createSocket({type: "udp4", reuseAddr: true});
|
|
socket.bind({port: udp.port, exclusive: true}, function(){
|
|
socket.setBroadcast(true);
|
|
socket.setMulticastTTL(128);
|
|
});
|
|
|
|
socket.on("listening", function(){
|
|
try { socket.addMembership(udp.address) }catch(e){ console.error(e); return; }
|
|
udp.peer = {id: udp.address + ':' + udp.port, wire: socket};
|
|
|
|
udp.peer.say = function(raw){
|
|
var buf = Buffer.from(raw, 'utf8');
|
|
if(udp.pack <= buf.length){ // message too big!!!
|
|
return;
|
|
}
|
|
socket.send(buf, 0, buf.length, udp.port, udp.address, noop);
|
|
}
|
|
|
|
console.log('Multicast on', udp.peer.id);
|
|
return; // below code only needed for when WebSocket connections desired!
|
|
setInterval(function broadcast(){
|
|
port = port || (opt.web && opt.web.address()||{}).port;
|
|
if(!port){ return }
|
|
udp.peer.say(JSON.stringify({id: opt.pid || (opt.pid = Math.random().toString(36).slice(2)), port: port}));
|
|
}, 1000);
|
|
});
|
|
|
|
socket.on("message", function(raw, info) { try {
|
|
if(!raw){ return }
|
|
raw = raw.toString('utf8');
|
|
if('2'===raw[0]){ return check(raw, info) }
|
|
opt.mesh.hear(raw, udp.peer);
|
|
|
|
return; // below code only needed for when WebSocket connections desired!
|
|
var message;
|
|
message = JSON.parse(raw.toString('utf8'));
|
|
|
|
if(opt.pid === message.id){ return } // ignore self
|
|
|
|
var url = 'http://' + info.address + ':' + (port || (opt.web && opt.web.address()||{}).port) + '/gun';
|
|
if(root.opt.peers[url]){ return }
|
|
|
|
//console.log('discovered', url, message, info);
|
|
root.$.opt(url);
|
|
|
|
} catch(e){
|
|
//console.log('multicast error', e, raw);
|
|
return;
|
|
} });
|
|
|
|
function say(msg){
|
|
this.to.next(msg);
|
|
if(!udp.peer){ return }
|
|
mesh.say(msg, udp.peer);
|
|
}
|
|
|
|
function check(id, info){ var tmp;
|
|
if(!udp.peer){ return }
|
|
if(!id){
|
|
id = check.id = check.id || Buffer.from(pid, 'utf8');
|
|
socket.send(id, 0, id.length, udp.port, udp.address, noop);
|
|
return;
|
|
}
|
|
if((tmp = root.stats) && (tmp = tmp.gap) && info){ (tmp.near || (tmp.near = {}))[info.address] = info.port || 1 } // STATS!
|
|
if(check.on || id === pid){ return }
|
|
root.on('out', check.on = say); // TODO: MULTICAST NEEDS TO BE CHECKED FOR NEW CODE SYSTEM!!!!!!!!!!
|
|
}
|
|
|
|
setInterval(check, 1000 * 1);
|
|
|
|
});
|