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); });