Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pubsub Won't Work Between Browser Node and Machine node (Daemon) #10

Closed
gil-air-may opened this issue Mar 21, 2019 · 2 comments
Closed
Assignees
Labels
help wanted Extra attention is needed

Comments

@gil-air-may
Copy link
Member

gil-air-may commented Mar 21, 2019

DEADLINE
27/03/2019

  • Version: js-ipfs: 0.34.4 and go-ipfs: 0.4.19
  • Platform: js-ipfs on Chrome v. 72.0.3626.121 and go-ipfs on 64-bit Windows 10

Objective

  • Enable Pubsub feature between IPFS node running on browser and IPFS running on local machine.

Overview of the Problem

We are trying to connect 2 nodes and get the Pubsub functionality working between them.

  • Node A is created programatically and runs in the browser. This node will Publish the message.
  • Node B runs as daemon in local machine, started via CLI. This node will Subscribe to a topic.

But, despite having tried several different configurations, we did not get the Pubsub feature working in this scenario.

Why is this necessary?

This behavior is required since it is part of our current strategy to pin the submitted ideas to IPFS, and make them available to the public in a decentralized way. Put simply, if we manage to achieve Pubsub between Node A and Node B, that means we can move forward with the POC app that we've been developing.

NODE A (browser) Current Config

First you need to require wrtc. This is necessary to setup a p2p connection between the 2 nodes:

const wrtc = require("wrtc"); // or require('electron-webrtc')
const WStar = require("libp2p-webrtc-star");
const wstar = new WStar({ wrtc });

Then you can instantiate the node by:

this.ipfsNode = new IPFS({
      EXPERIMENTAL: { pubsub: true },
      relay: { enabled: true, hop: { enabled: true } },
      config: {
        Addresses: {
          Swarm: [
            "/ip4/127.0.0.1/tcp/4001/ipfs/QmPMaDyK2ee95BpjnMyWYiVi46EcZFrY8AUmSzieNSLbEa",
            "/dns4/wrtc-star.discovery.libp2p.io/tcp/443/wss/p2p-webrtc-star"
          ]
        },
        libp2p: {
          modules: {
            transport: [wstar],
            peerDiscovery: [wstar.discovery]
          }
        }
      }
    });

NODE B (daemon) Current Config

Once you install IFPS on your machine and run ipfs start from the terminal, a folder named .ipfs will be created in your $HOME directory. Inside that folder, you will find a config file. The current state of my file is:

{
  "API": {
    "HTTPHeaders": {}
  },
  "Addresses": {
    "API": "/ip4/127.0.0.1/tcp/5001",
    "Announce": [],
    "Gateway": "/ip4/127.0.0.1/tcp/8080",
    "NoAnnounce": [],
    "Swarm": [
      "/ip4/0.0.0.0/tcp/4001",
      "/ip6/::/tcp/4001"
    ]
  },
  "Bootstrap": [
    "/dnsaddr/bootstrap.libp2p.io/ipfs/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
    "/dnsaddr/bootstrap.libp2p.io/ipfs/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
    "/dnsaddr/bootstrap.libp2p.io/ipfs/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
    "/dnsaddr/bootstrap.libp2p.io/ipfs/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
    "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
    "/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
    "/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
    "/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
    "/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
    "/ip6/2604:a880:1:20::203:d001/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
    "/ip6/2400:6180:0:d0::151:6001/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
    "/ip6/2604:a880:800:10::4a:5001/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
    "/ip6/2a03:b0c0:0:1010::23:1001/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd"
  ],
  "Datastore": {
    "BloomFilterSize": 0,
    "GCPeriod": "1h",
    "HashOnRead": false,
    "Spec": {
      "mounts": [
        {
          "child": {
            "path": "blocks",
            "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2",
            "sync": true,
            "type": "flatfs"
          },
          "mountpoint": "/blocks",
          "prefix": "flatfs.datastore",
          "type": "measure"
        },
        {
          "child": {
            "compression": "none",
            "path": "datastore",
            "type": "levelds"
          },
          "mountpoint": "/",
          "prefix": "leveldb.datastore",
          "type": "measure"
        }
      ],
      "type": "mount"
    },
    "StorageGCWatermark": 90,
    "StorageMax": "10GB"
  },
  "Discovery": {
    "MDNS": {
      "Enabled": true,
      "Interval": 10
    }
  },
  "Experimental": {
    "FilestoreEnabled": false,
    "Libp2pStreamMounting": false,
    "P2pHttpProxy": false,
    "QUIC": false,
    "ShardingEnabled": false,
    "UrlstoreEnabled": false
  },
  "Gateway": {
    "APICommands": [],
    "HTTPHeaders": {
      "Access-Control-Allow-Headers": [
        "X-Requested-With",
        "Range",
        "User-Agent"
      ],
      "Access-Control-Allow-Methods": [
        "GET"
      ],
      "Access-Control-Allow-Origin": [
        "*"
      ]
    },
    "NoFetch": false,
    "PathPrefixes": [],
    "RootRedirect": "",
    "Writable": false
  },
  "Identity": {
    "PeerID": "QmPMaDyK2ee95BpjnMyWYiVi46EcZFrY8AUmSzieNSLbEa",
    "PrivKey": "CAASqAkwggSkAgEAAoIBAQD1er6xc6EPjYtGjMV4W/uEs4uM17Zsm85S0nl/IgkcgJBxPPK82EGiIy3Z2BXqi9k018cmlR35WWLoyqPmqgRvQ4nBuWPTCmak/FoqBfJ7AxRovsb1NGPBhycHKSI+d0KaynpLZ+GLVgGU13cbu+viLEfIWa53GndVkpvYPFzDVBkvZRT6nkPsVemqfHiOPBgtjYDtij48fJU9Bl1cTfJ3EcuTpaEA+QhlqPHUsWUh4cmE/Ln5LSxR47zEIT2eYa9LIPPx328ZiSq6Lh1AGO4fe7j5B8L3ZPQYnLz+cBMftS2tlM4V3J6fqyqIl1sRKdKPHMUj8epB0EcKjyRaHWkjAgMBAAECggEAGgN8688mFUDZrotCbePJfqGMO0uswEuujKZTS76umn+hTu63hn2gTu9Nb5VvlSBmzyvCpfsNZxwq2CKJRetkduoAUjA0POwQPpGjeGqS7KhB5Gu7J8b6f0q0PxUD1PzMaRzl4tHKW/qsRjqjG6RJdfldTgT68RIz7TSRIVQcPHKa6E3t/QVzgQJcK6xQehGtOJ7PlSo8cHQRaxcNesUQyG4N0x4UfF+MqVme52HXZOn6OhzDdhjboHm0zzfhLil1r2AbgdGMWEzRp68OVtSAjjk5CN6EPuOmsck+22c1lV7wFfLctbv7sXuDDYtG1+24sx69AyQldgBXnsKf3lsX8QKBgQD1s+qliofUZIdN9bPaxEfKSfi607jQ3qJCnKlOvXtzO+v01yKDZ+0Qa5EeFOoK05V2xaw9mFstnefUPfid8B84+YOtCHcGyZmI8DJRmjHkxQHVHJB8lI82gz++k7jn4fUh7Ajb40S+RC/rw0XPcNR8HrzFcG+Tye70+IjswUAnWwKBgQD/xG6qdEYKcMYfoXNZ6d7NtlCJWs+P19gdprkdcfE3/0qd4+uOvptbW6dkPo2i9870HydKeTXmB94Tw81EcrSW8mjwSn9wibD4SInIjlE4EQUtsMPno2Hm0Jnmw9fUCx7o0OH+C364rX1dCBk+itKRfweQdYDEdMqEfheEyO632QKBgQDehqsecH+iWcW9UqkomhoW2LXfpv88lFZKlA421R+odv21yt5kOsyW0YUlxHVPht9YKaFcS89QWjHrpJC1ohL1C+442XDLgex+/GPmSgukENUfCPbHDdlC2s3xsWKHCLt1lItVctkApUrtcPaZ8KtRGpmHC9TR+dJkpW+FVWTf/wKBgQCf6SHD4uSzvGSy/A+R5N4PwfBCoItrhOkzSL0ugsHtX+k4JHtviQ67JOfYjh+iB8vV5/B56KThSIP52Y7qP8lXIwKnUfyx0PTblwbGZOy04DdbpMwndIhOdpfypvm3MqjFqWvSmT9Gmfnqg5i8+LDElSaWlFDJA7hm9CsiMzrFqQKBgFU4PH7KiraRaTtCNvXai4Lv7XXgnjhnUtE/enzvylCngmdF7sjxq1IQV8pNdKWqAx2yputUfOZGQgi/w2CC52svyEjrWv/NghACSCO5mMbMZc/cHPP54vt9lR2NqbnPnYZPcWym5kj3kCtCqpvDKnbDx4VhFhdxw8/yHM7N1r5+"
  },
  "Ipns": {
    "RecordLifetime": "",
    "RepublishPeriod": "",
    "ResolveCacheSize": 128
  },
  "Mounts": {
    "FuseAllowOther": false,
    "IPFS": "/ipfs",
    "IPNS": "/ipns"
  },
  "Pubsub": {
    "DisableSigning": false,
    "Router": "",
    "StrictSignatureVerification": false
  },
  "Reprovider": {
    "Interval": "12h",
    "Strategy": "all"
  },
  "Routing": {
    "Type": "dht"
  },
  "Swarm": {
    "AddrFilters": null,
    "ConnMgr": {
      "GracePeriod": "20s",
      "HighWater": 900,
      "LowWater": 600,
      "Type": "basic"
    },
    "DisableBandwidthMetrics": false,
    "DisableNatPortMap": false,
    "DisableRelay": false,
    "EnableAutoNATService": true,
    "EnableAutoRelay": true,
    "EnableRelayHop": false
  }
}

The Problem

I start the daemon on the terminal using:
ipfs daemon --enable-pubsub-experiment and subscribe to the topic using ipfs pubsub sub testing123

I navigate to localhost:3000 and the console logs:

Swarm listening on /p2p-circuit/ip4/127.0.0.1/tcp/4001/ipfs/QmPMaDyK2ee95BpjnMyWYiVi46EcZFrY8AUmSzieNSLbEa/ipfs/QmcCnVBpYLvcRLbutwRMkzeJwHfjbFaq8y9JQ2sLcBAX1L

Cool. So looks like the p2p circuit is online! So next we upload a file IPFS and save the CID to the state. (this.state.added_file_hash)

Then on the browser, we try to communicate with the daemon using

publishFileHash() {

    const topic = "testing123";
    const msg = Buffer.from(this.state.added_file_hash);
    console.log("msg is");
    console.log(this.state.added_file_hash);

    this.ipfsNode.pubsub.publish(topic, msg, err => {
      if (err) {
        return console.error(`failed to publish to ${topic}`, err);
      }
      console.log(`published to ${topic}`);
    });
  }

After this, browser console logs: published to testing123 but the daemon does not get the message. 😢

Why P2P Circuit? Did you try a direct connection

So maybe Pubsub does not work with P2P circuits. However, I could not find a way to get a direct connection between the browser node and the daemon node.

If you use:

publishFileHash() {
    const addr =
      "/ip4/127.0.0.1/tcp/4001/ipfs/QmPMaDyK2ee95BpjnMyWYiVi46EcZFrY8AUmSzieNSLbEa";
    this.ipfsNode.swarm.connect(addr, function(err) {
      if (err) {
        throw err;
      }
      const topic = "testing123";
      const msg = Buffer.from(this.state.added_file_hash);
      console.log("msg is");
      console.log(this.state.added_file_hash);

      this.ipfsNode.pubsub.publish(topic, msg, err => {
        if (err) {
          return console.error(`failed to publish to ${topic}`, err);
        }
        console.log(`published to ${topic}`);
      });
    });
  }

You get an browser console logs an error that says:

image

I want to contribute but I'm not sure where to start...

If you would like to know more about why solving this task is critical, feel free to reach out to me or @abinashk 😃 Right now this is our priority. If you're up for the challenge, I can also help setting up Node A and Node B so you can aid us to reach a conclusion 🥇


@gil-air-may gil-air-may changed the title Pubsub won't work between browser node and machine node (daemon) Pubsub Won't Work Between Browser Node and Machine node (Daemon) Mar 21, 2019
@gil-air-may gil-air-may added the help wanted Extra attention is needed label Mar 21, 2019
@lidel
Copy link

lidel commented Mar 25, 2019

I could not find a way to get a direct connection between the browser node and the daemon node.

Hi, try enabling websocket transport in go-ipfs (eg. on /ip4/0.0.0.0/tcp/4003/ws):

Then browser and daemon will share a transport that both can use.

@gil-air-may
Copy link
Member Author

gil-air-may commented Apr 3, 2019

Thank you very much! Enabling websockets was the missing piece.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

7 participants