I'm attempting to have peers converse with each other based on multiple topics. Based on the hyperswarm hello world example, I have this:
const Hyperswarm = require('hyperswarm')
const swarm1 = new Hyperswarm()
const swarm2 = new Hyperswarm()
;(async () => {
swarm1.on('connection', (conn, info) => {
// swarm1 will receive server connections, expect empty topics for server mode...
console.log('swarm1 got connection', info.topics.map(x=>x.toString()),info._seenTopics)
conn.write('this is a server connection')
conn.end()
})
swarm2.on('connection', (conn, info) => {
console.log('swarm2 got connection', info.topics.map(x=>x.toString()),info._seenTopics)
conn.on('data', data => console.log('client got message:', data.toString()))
})
const topicA = Buffer.alloc(32).fill('TopicA')
const topicB = Buffer.alloc(32).fill('TopicB')
const discovery = swarm1.join(topicA, { server: true, client: false })
await discovery.flushed()
console.log('discovery flushed')
const discovery1 = swarm1.join(topicB, { server: true, client: false })
await discovery1.flushed() // Waits for the topic to be fully announced on the DHT
console.log('discovery1 flushed')
swarm2.join(topicA, { server: false, client: true })
console.log('swarm2 joined topicA:')
await swarm2.flush() // Waits for the swarm to connect to pending peers.
console.log('swarm2 topicA flushed')
swarm2.join(topicB, { server: false, client: true })
console.log('swarm2 joined topicB:')
await swarm2.flush()
console.log('swarm2 topicB flushed')
})();
This gives an output of:
discovery flushed
discovery1 flushed
swarm2 joined topicA:
swarm1 got connection [] Set(0) {}
This seems to hang on the first await swarm2.flush()
call. Is there an alternative approach? Might it be better to create a swarm object per topic?
Update:
Here is a version with per-swarm topics:
const Hyperswarm = require('hyperswarm')
const TopicAServerSwarm = new Hyperswarm()
const TopicBServerSwarm = new Hyperswarm()
const TopicAClientSwarm = new Hyperswarm()
const TopicBClientSwarm = new Hyperswarm()
;(async () => {
TopicAServerSwarm.on('connection', (conn, info) => {
console.log('TopicAServerSwarm got connection', info.topics.map(x=>x.toString(0)),info._seenTopics)
conn.write('this is a server connection for TopicA')
conn.end()
})
TopicBServerSwarm.on('connection', (conn, info) => {
console.log('TopicBServerSwarm got connection', info.topics.map(x=>x.toString(0)),info._seenTopics)
conn.write('this is a server connection for TopicB')
conn.end()
})
TopicAClientSwarm.on('connection', (conn, info) => {
console.log('TopicAClientSwarm got connection', info.topics.map(x=>x.toString(0)),info._seenTopics)
conn.on('data', data => console.log('client got message:', data.toString()))
})
TopicBClientSwarm.on('connection', (conn, info) => {
console.log('TopicBClientSwarm got connection', info.topics.map(x=>x.toString(0)),info._seenTopics)
conn.on('data', data => console.log('client got message:', data.toString()))
})
const topicA = Buffer.alloc(32).fill('TopicA')
const topicB = Buffer.alloc(32).fill('TopicB')
const discovery = TopicAServerSwarm.join(topicA, { server: true, client: false })
await discovery.flushed()
console.log('TopicAServerSwarm flushed')
const discovery1 = TopicBServerSwarm.join(topicB, { server: true, client: false })
await discovery1.flushed() // Waits for the topic to be fully announced on the DHT
console.log('TopicBServerSwarm flushed')
const discoverycliA = TopicAClientSwarm.join(topicA, { server: false, client: true })
console.log('TopicAClientSwarm joined topicA:')
await discoverycliA.flushed() // Waits for the swarm to connect to pending peers.
console.log('TopicAClientSwarm flushed')
const discoverycliB = TopicBClientSwarm.join(topicB, { server: false, client: true })
console.log('TopicBClientSwarm joined topicB:')
await discoverycliB.flushed()
console.log('TopicBClientSwarm flushed')
})();
Again, here, the server swarms get connections but not the clients? Why might this be happening?
There were a few errors in my code in the question. I modelled two simulated peers with two IIFEs like so:
This gave:
The client is able to detect the topics and can react as necessary, from the readme:
Essentially, hyperswarm gives you a websocket connection to a peer that is interested in given topic(s) and assigns client and server roles. If there are multiple topics, it's up to the developer to use the provided websocket to create the necessary procedures to send/receive information pertaining to those topics.
Though I'm still not sure how it decides which peers acts as a client and which as a server, but that's another question...