Compare commits
4 Commits
81191ed7ce
...
4f8918f8e9
Author | SHA1 | Date |
---|---|---|
Derrick Hammer | 4f8918f8e9 | |
Derrick Hammer | bebdc7d0d4 | |
Derrick Hammer | fcfdd51908 | |
Derrick Hammer | ce1854de83 |
|
@ -1 +1 @@
|
||||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAkBlC,eAAO,MAAM,YAAY,eAAuB,CAAC;AAEjD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,YAAY;IAChD,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,QAAQ,CAAS;gBAEb,EACV,OAAkB,EAClB,GAAS,EACT,aAAiB,EACjB,EAA2B,EAC3B,KAAY,EACZ,QAAmB,GACpB;;;;;;;KAAK;IAmBN,OAAO,CAAC,aAAa;IAkCrB,OAAO,CAAC,SAAS;IA+CjB,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,SAAW;IAenC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,SAAW;CAY1C"}
|
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAkBlC,eAAO,MAAM,YAAY,eAAuB,CAAC;AAIjD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,YAAY;IAChD,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,QAAQ,CAAS;gBAEb,EACV,OAAkB,EAClB,GAAS,EACT,aAAiB,EACjB,EAA2B,EAC3B,KAAY,EACZ,QAAmB,GACpB;;;;;;;KAAK;IAmBN,OAAO,CAAC,aAAa;IAkCrB,OAAO,CAAC,SAAS;IAqDjB,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,SAAW;IAenC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,SAAW;CAY1C"}
|
|
@ -20,6 +20,7 @@ const LRU_SIZE = 255;
|
||||||
const TTL = 255;
|
const TTL = 255;
|
||||||
const PROTOCOL = "lumeweb.flood";
|
const PROTOCOL = "lumeweb.flood";
|
||||||
exports.FLOOD_SYMBOL = Symbol.for(PROTOCOL);
|
exports.FLOOD_SYMBOL = Symbol.for(PROTOCOL);
|
||||||
|
const closedMap = new Map();
|
||||||
class DHTFlood extends events_1.default {
|
class DHTFlood extends events_1.default {
|
||||||
id;
|
id;
|
||||||
ttl;
|
ttl;
|
||||||
|
@ -74,14 +75,19 @@ class DHTFlood extends events_1.default {
|
||||||
async onopen() {
|
async onopen() {
|
||||||
self.emit("peer-open", peer);
|
self.emit("peer-open", peer);
|
||||||
},
|
},
|
||||||
async ondestroy() {
|
|
||||||
self.emit("peer-remove", peer);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
if (chan) {
|
if (chan) {
|
||||||
peer[exports.FLOOD_SYMBOL] = chan;
|
peer[exports.FLOOD_SYMBOL] = chan;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!closedMap.has(peer)) {
|
||||||
|
const close = () => {
|
||||||
|
self.emit("peer-remove", peer);
|
||||||
|
peer.removeListener("close", close);
|
||||||
|
closedMap.delete(peer);
|
||||||
|
};
|
||||||
|
peer.on("close", close);
|
||||||
|
}
|
||||||
chan = peer[exports.FLOOD_SYMBOL];
|
chan = peer[exports.FLOOD_SYMBOL];
|
||||||
if (!chan) {
|
if (!chan) {
|
||||||
throw new Error("could not find channel");
|
throw new Error("could not find channel");
|
||||||
|
|
16
src/index.ts
16
src/index.ts
|
@ -18,6 +18,8 @@ const PROTOCOL = "lumeweb.flood";
|
||||||
|
|
||||||
export const FLOOD_SYMBOL = Symbol.for(PROTOCOL);
|
export const FLOOD_SYMBOL = Symbol.for(PROTOCOL);
|
||||||
|
|
||||||
|
const closedMap = new Map();
|
||||||
|
|
||||||
export default class DHTFlood extends EventEmitter {
|
export default class DHTFlood extends EventEmitter {
|
||||||
private id: Buffer;
|
private id: Buffer;
|
||||||
private ttl: number;
|
private ttl: number;
|
||||||
|
@ -91,22 +93,28 @@ export default class DHTFlood extends EventEmitter {
|
||||||
let chan: any;
|
let chan: any;
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
if (!mux.opened({ protocol: this.protocol })) {
|
if (!mux.opened({ protocol: this.protocol })) {
|
||||||
chan = mux.createChannel({
|
chan = mux.createChannel({
|
||||||
protocol: this.protocol,
|
protocol: this.protocol,
|
||||||
async onopen() {
|
async onopen() {
|
||||||
self.emit("peer-open", peer);
|
self.emit("peer-open", peer);
|
||||||
},
|
},
|
||||||
async ondestroy() {
|
|
||||||
self.emit("peer-remove", peer);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
if (chan) {
|
if (chan) {
|
||||||
peer[FLOOD_SYMBOL] = chan;
|
peer[FLOOD_SYMBOL] = chan;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!closedMap.has(peer)) {
|
||||||
|
const close = () => {
|
||||||
|
self.emit("peer-remove", peer);
|
||||||
|
peer.removeListener("close", close);
|
||||||
|
closedMap.delete(peer);
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.on("close", close);
|
||||||
|
}
|
||||||
|
|
||||||
chan = peer[FLOOD_SYMBOL];
|
chan = peer[FLOOD_SYMBOL];
|
||||||
|
|
||||||
if (!chan) {
|
if (!chan) {
|
||||||
|
|
81
test.js
81
test.js
|
@ -1,62 +1,61 @@
|
||||||
const test = require('tape')
|
const test = require("tape");
|
||||||
const Hyperswarm = require('hyperswarm')
|
const Hyperswarm = require("hyperswarm");
|
||||||
const sodium = require('sodium-universal')
|
const sodium = require("sodium-universal");
|
||||||
const b4a = require('b4a')
|
const b4a = require("b4a");
|
||||||
const { default: DHTFlood } = require('./')
|
const { default: DHTFlood } = require("./");
|
||||||
const crypto = require('crypto')
|
const crypto = require("crypto");
|
||||||
|
|
||||||
const topicName = crypto.randomBytes(10)
|
const topicName = crypto.randomBytes(10);
|
||||||
|
|
||||||
test('Broadcast through several peers', (t) => {
|
test("Broadcast through several peers", (t) => {
|
||||||
const peer1 = createPeer()
|
const peer1 = createPeer();
|
||||||
const peer2 = createPeer()
|
const peer2 = createPeer();
|
||||||
const peer3 = createPeer()
|
const peer3 = createPeer();
|
||||||
t.plan(2)
|
t.plan(2);
|
||||||
|
|
||||||
Promise.all([peer1, peer2, peer3]).then((peers) => {
|
Promise.all([peer1, peer2, peer3]).then((peers) => {
|
||||||
const peer1 = peers.shift()
|
const peer1 = peers.shift();
|
||||||
const peer2 = peers.shift()
|
const peer2 = peers.shift();
|
||||||
const peer3 = peers.shift()
|
const peer3 = peers.shift();
|
||||||
|
|
||||||
const flood1 = new DHTFlood({ swarm: peer1 })
|
const flood1 = new DHTFlood({ swarm: peer1 });
|
||||||
const flood2 = new DHTFlood({ swarm: peer2 })
|
const flood2 = new DHTFlood({ swarm: peer2 });
|
||||||
const flood3 = new DHTFlood({ swarm: peer3 })
|
const flood3 = new DHTFlood({ swarm: peer3 });
|
||||||
const data = Buffer.from('Hello World')
|
const data = Buffer.from("Hello World");
|
||||||
|
|
||||||
flood1.on('message', () => t.error('Got own message'))
|
flood1.on("message", () => t.error("Got own message"));
|
||||||
|
|
||||||
flood2.on('message', (message) => {
|
flood2.on("message", (message) => {
|
||||||
t.deepEquals(message, data, 'Data got broadcast')
|
t.deepEquals(message, data, "Data got broadcast");
|
||||||
})
|
});
|
||||||
flood3.on('message', (message) => {
|
flood3.on("message", (message) => {
|
||||||
t.deepEquals(message, data, 'Data got broadcast')
|
t.deepEquals(message, data, "Data got broadcast");
|
||||||
})
|
});
|
||||||
|
|
||||||
function maybeFlood() {
|
function maybeFlood() {
|
||||||
if (peer1.peers.size === 2) {
|
if (peer1.peers.size === 2) {
|
||||||
flood1.broadcast(data)
|
flood1.broadcast(data);
|
||||||
|
peer1.removeListener("connection", maybeFlood);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
peer1.on('connection', () => {
|
peer1.on("connection", maybeFlood);
|
||||||
maybeFlood()
|
|
||||||
})
|
|
||||||
|
|
||||||
t.teardown(() => {
|
t.teardown(() => {
|
||||||
[peer1, peer2, peer3].forEach((item) => item.destroy())
|
[peer1, peer2, peer3].forEach((item) => item.destroy());
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
async function createPeer() {
|
async function createPeer() {
|
||||||
const swarm = new Hyperswarm()
|
const swarm = new Hyperswarm();
|
||||||
await swarm.dht.ready()
|
await swarm.dht.ready();
|
||||||
await swarm.listen()
|
await swarm.listen();
|
||||||
|
|
||||||
const topic = b4a.allocUnsafe(32)
|
const topic = b4a.allocUnsafe(32);
|
||||||
sodium.crypto_generichash(topic, b4a.from(topicName))
|
sodium.crypto_generichash(topic, b4a.from(topicName));
|
||||||
|
|
||||||
swarm.join(topic)
|
swarm.join(topic);
|
||||||
|
|
||||||
return swarm
|
return swarm;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue