mafintosh / discovery-swarm

A network swarm that uses discovery-channel to find peers
MIT License
374 stars 57 forks source link

How to bind multiple hyperdb to one swarm? #51

Open helloyou2012 opened 6 years ago

helloyou2012 commented 6 years ago

I want to bind multiple hyperdb to one swarm and here's what I did. I wonder if there is a better way?

import protocol from 'hypercore-protocol';
import discovery from 'discovery-swarm';
import swarmDefaults from 'dat-swarm-defaults';

const dbByKey = {};
const dbByDKey = {};

const swarm = discovery(swarmDefaults({
  stream() {
    const stream = protocol({
      id: crypto.randomBytes(32),
      live: true
    });
    stream.on('feed', (dkey) => {
      const db = dbByDKey[dkey.toString('hex')];
      if (!db) return;
      // Change key and userData
      stream.__key = db.key.toString('hex');
      stream.userData = JSON.stringify({
        key: db.local.key.toString('hex')
      });
      db.replicate({ stream, live: true });
    });
    stream.on('handshake', () => {
      if (!stream.remoteUserData) return;
      let data = null;
      try {
        data = JSON.parse(stream.remoteUserData);
      } catch (e) {
        console.error(e);
        return;
      }

      const db = dbByKey[stream.__key];
      if (!db) return;

      const lkey = Buffer.from(data.key, 'hex');
      db.authorized(lkey, (err, auth) => {
        if (err) return callback(err);
        if (!auth) {
          db.authorize(lkey, (err) => {
            if (err) return callback(err);
            callback();
          });
        }
      });
    });
    return stream;
  },
  utp: true,
  tcp: true
}));

swarm.on('error', err => console.error('Swarm error', err));
swarm.on('listening', () => console.log('Swarm listening'));
swarm.listen(11111);