2

Here's a link to a basic code pen that syncs an <input> tag with a Gun instance, and wires Gun updates to React setState.
https://codepen.io/anon/pen/weJxNO?editors=0011

What I expect:
When you open the program in several windows, you can type in one window and see the updates in the others. Typing in one window alters the Gun store, which then causes all instances to propagate events, thus re-rendering all the React components across windows.

What actually happens:
If you open the program in several windows, observe that typing in one window changes the localStorage value for all windows. Yet only the window in which you are actually typing registers events from the Gun store.

Possible solution:
I understand I can set up a single Gun instance on a server that all my clients commune with. But isn't this antithetical to Gun's purpose? The advantage of p2p systems is that you don't need a central source of authority.

Question restated:
How do I wire the program so that all Gun instances fire change events, thus updating every React component across windows, without a central server?

Relevant code from Codepen:

class App extends React.Component {
  constructor() {
    super()
    this.state = {name: ''};
    this.gun = Gun()
  }

  componentDidMount() {
    this.gun.get('user').on(
      ({ name }) => 
        this.setState({ name }))
  }
  render() { 
    return <div>
      <h1>Hey, {this.state.name || '(your name here)'}</h1>
      <input 
        value={this.state.name}
        placeholder="edit your name here"
        onChange={({ target }) => 
          this.gun.get('user')
             .put({ name: target.value })}
       />
      <p>you should see updates in multiple browser windows</p>
      <p>you can see your localStorgae update every time you type in other windows</p>
      <p>but the state is only set when you type in this window</p>
    </div>
  }
}
Joseph Fraley
  • 1,360
  • 1
  • 10
  • 26

3 Answers3

4

While WebRTC still requires a signaling server, unfortunately browsers (not GUN) still need 1+ relay peers.

It is possible to do P2P updates using GUN without a central server on non-browser peers. Browsers are limited in their P2P abilities, this is not GUN's fault.

marknadal
  • 7,534
  • 4
  • 25
  • 22
  • Is this still the case with browsers that have support for webrtc? I understand that there will be NAT issues with clients behind symmetric NATs. Assuming an ideal situation where both peer A and peer B have webrtc enabled browsers, and ignoring the NAT issue, can they sync data without a relay peer(solely relying on webrtc)? Webrtc requires signalling and stun/turn servers, so without relay peer how do you connect a peer? Basically, I want to understand the case where it's just `Gundb` and `Webrtc` (no relay/central server). P.S: I love GunDb, Pied Piper!!!! – John Yepthomi Oct 06 '22 at 06:07
  • I found an answer you posted here https://stackoverflow.com/questions/37863163/specific-questions-about-gundb-as-a-standalone-db-for-a-cordova-project that clearly explains the webrtc question i had. Sorry to bother. – John Yepthomi Oct 06 '22 at 06:23
1

So according to Gun's Getting Started guide: https://github.com/amark/gun/wiki/Getting-Started-%28v0.3.x%29#how-to

In order to sync data between two peers, you'll need at least one gun server.

Thus, the expected behavior in my question is impossible, and the expectation is based on a misunderstanding of the technology - inspired in part a little by the documentation.

My misunderstanding was in the meaning of distributed systems, as described here https://github.com/amark/gun#why:

GUN is peer-to-peer by design, meaning you have no centralized database server to maintain or that could crash. This lets you sleep through the night without worrying about database DevOps - we call it "NoDB".

This comment originally confused me next to the former comment. If I need at least one gun server to get connections to update in real time, then can't that one server sometimes crash and wreck my app?

The answer is that if your server crashes then your real-time bridge will of course break. But your data will not be destroyed. Because the users will all federate the data back to eachother when the connection is eventually re-established using the distributed conflict-resolution algorithm. For more insight into this, see this video of Gun's creator doing some live programming with Gun: https://youtu.be/qJNDplwJ8aQ?list=PL9EMvPaQlrL9mgmihQNcKdqmZTcmxFG__

You can find a brief technical explanation for why the Gun server is needed to relay messages to all clients at the end of the answer to this stackoverflow question: Specific questions about gunDB as a standalone DB for a Cordova project

*WebRTC requires STUN/ICE/signaling servers to bootstrap the WebRTC connection. Which is super annoying. This means that even though WebRTC is P2P, in order to get connected you have to go through some server and this has to happy for every page load. Because of this, we by default bundle gun with websockets/JSONP that it has to connect to a gun relay server peer (there are also so community gun relay peers that people can use for personal experiments, but it is easy to run your own as in Point4). As a result, we haven't released a WebRTC adapter yet, despite the fact that WebRTC + gun is a perfect fit - stupid STUN/ICE/signaling servers.

Joseph Fraley
  • 1,360
  • 1
  • 10
  • 26
0

You probably want to subscribe to a change event in local storage. Have a look here:

https://developer.mozilla.org/en-US/docs/Web/Events/storage

Leon
  • 542
  • 1
  • 6
  • 15
  • I understand how that would work, but I'm still confused by Gun then. See https://github.com/amark/gun#why << "GUN is peer-to-peer by design, meaning you have no centralized database server to maintain or that could crash." >> How is this true if the clients all need to commune with a server instance to propagate the change events? – Joseph Fraley Jun 20 '17 at 00:15
  • Just to elaborate on that point: the official gun starter app https://github.com/gundb/gun-starter-app starts with a server file, and really that's what I'm confused by, and what I'd expect people using Gun want to avoid? – Joseph Fraley Jun 20 '17 at 00:24
  • Don't have time to go into detail (gotta catch the CalTrain in a few minutes)... but the BROWSER even with WebRTC unfortunately requires bootstrapping/signaling servers. So although GUN is P2P the browser needs a relay server. If you are running GUN in an Electron app or just as NodeJS instances... you can then do fully P2P connections by listing their IPs as peers. I'll expand more later and see if it makes sense to also post an answer (thanks everybody else for helping out so far), but yes Leon is right that an adapter for localStorage events between same-machine/browser tabs could work. – marknadal Jun 21 '17 at 17:57