Trouble Using PubSub in Browser & Discrepancy in the Docs

Looking at the JS API documentation the pubsub.publish() function should return either a success or an error.

This is how I’m calling the function:

async publish(libp2p) {
  await libp2p.pubsub.publish('$7h1515N074G4m3!', Buffer.from(libp2p.peerInfo.id.toB58String())).then(success=>{
    console.log(`Was Published: ${success}`);
  }).catch(err=>{console.log(err);})
}

What should result is all other nodes that have a route to mine and are subbed to ‘$7h1515N074G4m3!’ should receive my peerInfo.id in the msg.data on the other end. Instead I am returned an undefined value as “Was published: undefined” and no msg is received on the other end(another tab of a different instance of the same WebApp).

I noticed when looking at /js-libp2p/examples/pubsub/README.md the pubsub.publish() function is executed synchronously(rather on an interval basis but not waiting to return a promise) and the pubsub.subscribe() function is being used with await. This arrangement makes sense to me as you need to wait for messages to arrive after subscribing to the topic, and you don’t really need to wait for anything after publishing.

So why does the /js-libp2p/doc/API.md specify the reverse? Where pubsub.subscribe() returns void, and pubsub.publish() is supposed to return a success Promise. I receive the undefined value when using both Floodsub or Gossipsub.

The list of peers I’m connected to while doing this is:

  • ‘/dns4/ams-1.bootstrap.libp2p.io/tcp/443/wss/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd’,
  • ‘/dns4/lon-1.bootstrap.libp2p.io/tcp/443/wss/p2p/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3’,
  • ‘/dns4/sfo-3.bootstrap.libp2p.io/tcp/443/wss/p2p/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM’,
  • ‘/dns4/sgp-1.bootstrap.libp2p.io/tcp/443/wss/p2p/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu’,
  • ‘/dns4/nyc-1.bootstrap.libp2p.io/tcp/443/wss/p2p/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm’,
  • ‘/dns4/nyc-2.bootstrap.libp2p.io/tcp/443/wss/p2p/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64’

And my node configuration is this:

  const libp2p = await Libp2p.create({
     modules: {
       transport: [Websockets],
       connEncryption: [Secio],
       streamMuxer: [Mplex],
       peerDiscovery: [Bootstrap],
       pubsub: Floodsub/Gossipsub,
       dht: DHT
     },
     config: {
       autoDial: true,
       peerDiscovery: {
         bootstrap: {
           interval: 60e3,
           enabled: true,
           list: this.state.bootstrappedPeers
         }
       },
       dht: {
         enabled: true
       }
     }
  })

I suppose it’s possible, as the nodes I’m bootstraping were provided by one of the examples, that they don’t support pubsub which is why I’m not getting a success or an error? As in, my code is correct, so no error, but pubsub isn’t supported by those nodes, so no success either?

I suppose it’s possible, as the nodes I’m bootstraping were provided by one of the examples, that they don’t support pubsub which is why I’m not getting a success or an error? As in, my code is correct, so no error, but pubsub isn’t supported by those nodes, so no success either?

If you are not directly connected to peers who support pubsub your messages won’t be forwarded.

The main reason publish returns a promise is that it needs to take some asynchronous encryption action. If you don’t have any peers to publish to it doesn’t look like we’re throwing any errors, we should be so that applications can make informed decisions about what to do with the data to be published (retry, etc).

The issue with making subscribe async is that it’s an ongoing process. Anytime we connect to a new pubsub peer we will exchange subscriptions and “subscribe” with them.

It sounds like your issue may be due to your peers not being on the same pubsub overlay (middle peers don’t support it). I think publish throwing an error when no peers are available would help with diagnosing this. Would you mind creating a github issue for this?