2

I thought gun instance in the server was also one of the peers. But when I put data on the server, the peer can't get the data.

Here is my simple test code.

global.gun.get('servertest').put('yes'); // at server side
gun.get('servertest').once(console.log); // at client side

And it prints undefined. please, let me know how to use a gun instance on server side.

huhsame
  • 73
  • 1
  • 9
  • 1
    this might be a bug currently with AXE, could you try `Gun({axe: false` + make sure things are setup for connections like @skiqh said & always use `.on(` while debugging like @hadar-rottenberg mentioned. Let us know if it works! So proud everyone else has been jumping in to help too <3 <3 <3 ! – marknadal Feb 26 '20 at 20:49
  • Thank everyone. I tried suggestions and It turned out that I put the data on the root of gun data as @rogowski let me know in discord. so now it works. It was my mistake. https://gun.eco/docs/API#unexpected-behavior – huhsame Feb 27 '20 at 05:28

3 Answers3

2

On the server, run this to actually accept remote connections:

var server = require('http').createServer().listen(8080);
var gun = Gun({web: server});

On the client, run this to connect to your server:

var gun = Gun({peers: ["http://server-ip-or-hostname:8080/gun"]})

As a side note, even if you establish a peer connection to get your data, you still need to handle undefined, as once() might fire several times as data is coming in.

Relevant links:


EDIT: To be more explicit about my side note above -- the once callback on your client getting undefined for non-local data is actually by design. It means the client does not have the requested data available yet. It will however request it from its peers, which will try to answer with what they themselves can resolve (locally or from their respective peers). These answers will trigger the callback again (if they got through the CRDT algorithm I think).

Getting undefined on the client could also mean the server's response might have timed out and GUN considered it unanswered. You can prolong the waiting time with .once(callback_function, {wait: time_in_miliseconds}).

As per Hadar's answer, try using on() instead of once() to mitigate race conditions, i.e. your client requesting data from the server before you actually wrote it. Once you got your data and don't want any more updates, you can unsubscribe with gun.get('servertest').off()

Also, it might be noteworthy that GUN instances are not magically linked; having two of them connected does not mean they are one and the same in any way. Conceptually, they are peers in a distributed system, which in GUN's case gives you eventual consistency with all the limits and tradeoffs associated with that.

skiqh
  • 465
  • 2
  • 12
  • Thanks for your answer. I already what you wrote before trying that code in my question :( I want to figure out how to use `.put()` method on the server-side like on the client-side. – huhsame Feb 26 '20 at 11:28
  • here is my code in detail!!!! I initiated gun instance well. ```let server = https.createServer(options, app); server.listen( port ); let gun = Gun({ file: 'data', web: server }); global.gun = gun; global.gun.get('servertest').put('yes');``` on server-side and ```let opt = {}; opt.store = RindexedDB(opt); opt.localStorage = false; opt.peers = ['https://d.wxr.onl/gun']; G.gun = Gun(opt);``` on the client side. – huhsame Feb 26 '20 at 11:29
  • oh looks confusing. I will write it again – huhsame Feb 26 '20 at 11:33
1

@skiqh

Hello, Thanks for your answer. I initiated gun instance well in both server and client.

  1. server
let server =  https.createServer(options, app);
server.listen( port );
let gun = Gun({ file: 'data', web: server });
global.gun = gun;  // <-- my gun instance on server side

global.gun.get('servertest').put('yes'); <-- I tried to put data 

// listening~~~~~ 
  1. client
    window.G = G;
    let opt = {};
    opt.store = RindexedDB(opt);
    opt.localStorage = false;
    opt.peers = ['https://my.link/gun'];

    G.gun = Gun(opt); // <-- my gun instance on client

    gun.get('servertest').once(console.log) // <-- it prints "undefined" even though I put data here by server!

I really want to know how to use methods like .put(), .get(), .on() etc.. on the server side using gun instance.

I tried doing this but failed as I attached the result on my post.

Please, Let me know what Im doing something wrong and the correct way. Thank you

huhsame
  • 73
  • 1
  • 9
0

try gun.on instead of once. on will subscribe to all changes. your example should work if you run .once only after you write something to the server. using gun.on on client should work regardless and will trigger the moment the server write somehting