Hi, I am currently in the process of building a simple multiplayer game. I was going to use Gun, but I can't find an "onDisconnect" function in the API. I need it so if a player closes the browser, their data is removed. Firebase has this function as well. Does it exist?
Here is firebase's version of it
https://www.firebase.com/docs/web/api/ondisconnect/
Sadly, gun doesn't currently have an onDisconnect method :disappointed:
Most tools like sock.js or socket.io include the constant heartbeat polling built in, but since we want gun core to stay lean on dependencies and maintain control over backwards compatibility, we built our own lightweight websocket/jsonp transport layers.
There are a few ways it could be built (in ascending complexity):
The easiest way, building it on top of gun, might have each player updating a value every second or so, and listening for those updates on the server and marking them as disconnected after an interval of inactivity. Since you're moving through the gun abstraction, that method will likely be slower than a plain websocket implementation.
It would be best to hook into the existing websocket connection and broadcast the heartbeat from the clients and intercept on the server(s), but I need to defer to @amark for more details there. I think this is the simplest and most promising option.
The third option would replace the core transport layer with a socket.io/sock.js plugin and let them handle the heartbeat for you. If you're interested, let us know in our gitter channel and we'll help out!
I wish it were as easy as an API call, but we're intentionally trying to keep gun lean and unopinionated so we don't restrict the ability of others to build abstractions and modules on top. However, if we gang up on @amark, we might be able to convince him to expose more control over his websockets plugin :grinning:
Wow, thanks for the in depth answer!
I was working with socket.io before I saw gun, and I didn't like how much work I had to do just to transmit a few arrays. I still think this should be built in to gun, because many other databases appear to have them, but for now I think I'll use socketio for disconnects (as a separate Server or something), and gun for actual data.
How would I do it through the existing websockets?
@Ajusa got slightly confused with your last message. Are you wanting to know how to swap Socket.io into GUN rather than websockets? Or were you saying that Socket.io was difficult to transmit data (or gun was)?
@PsychoLlama had a pretty complete answer. Websockets has a hardware level "disconnect" event, however I haven't coded it to do anything useful yet (https://github.com/amark/gun/blob/master/lib/ws.js#L37-L38), and this is serverside only - if you have any ideas on how we could improve this piece that'd be great (note: we'd need to apply it to the fallback of JSONP as well).
I still think the simplest solution would be to just have a "connected" property for each user in GUN that you have each user update every 1second (with a setInterval). Then any other peer (serverside or not) can check if their connected property is older than 5seconds (latency/hiccups/etc) and if it is, they probably got disconnected.
What is your game? Have any demos up?
You've seen Jesse's http://trace.gunDB.io/ ? :D
You'd be proud, Jesse @PsychoLlama .
Okay. Sorry for being unclear in my last message, but I meant to say that I have implemented Websockets in my game, didn't like it, then switched to Socket.IO. However, I don't want to worry about server code right now and want to focus on the client side.
What you said about a property value makes a lot of sense, user disconnects after 5 seconds. I will probably go about implementing that. I still think this would be useful in GUN, but I can make do without.
My game is at ajusa.github.io/Spell
src at www.github.com/ajusa/Spell
EDIT: I don't know what to do if the user's date/time are broken, but I will try to figure it out. Then the time value would always be in the future or in the past.
Sounds good! Nice start on the game! Hit up the http://gitter.im/amark/gun if you need anything/keep us updated on it.
Okay, thanks!
Is this still open? Maybe someone will make a heartbeat-like plugin.
Right now it attempts to auto-reconnect with a backoff. Here is the close callback for websocket, maybe you could do a quick pull request to emit an event? Gun.on('ws-close').emit(c) or something like that.
https://github.com/amark/gun/blob/master/gun.js#L1323
I'm cleaning up issues... this is definitely something a couple people have asked about. I'm unsure if this is something that the database itself should handle (it has to be implemented in the transport layer anyways). I still recommend people go with the heartbeat approach (it might seem hacky, but it is the "correct" way to deal with this).
I'm worried socket-specific disconnects/events won't necessarily reflect a "player" (because a player might switch between devices, tabs, etc.) so I'm gonna close this as "not a bug" for now. Although I still think it is an interesting discussion and that it should be continued, to explore its merits. :)
Most helpful comment
Right now it attempts to auto-reconnect with a backoff. Here is the close callback for websocket, maybe you could do a quick pull request to emit an event?
Gun.on('ws-close').emit(c)or something like that.https://github.com/amark/gun/blob/master/gun.js#L1323