camchenry / sock.lua

A Lua networking library for LÖVE games.
https://camchenry.github.io/sock.lua/
MIT License
175 stars 7 forks source link

Any way to expedite disconnect event? #19

Closed prashantgupta24 closed 3 years ago

prashantgupta24 commented 3 years ago

First of all, thanks a lot for this amazing library! This solved so many issues that I was having in creating a multi player game.

My question is regarding the disconnect event. I put this code in my server,

server:on("disconnect", function(data, client)
        print('client disconnected : ', client)
    end)

but for some reason it takes a long time (~10-15 seconds) before the callback happens on the server after a client has disconnected.

Is there a way to expedite this callback? Is this delay because of enet and UDP?

camchenry commented 3 years ago

@prashantgupta24 It sounds like clients are disconnecting by default (i.e., timeout). If users are quitting voluntarily, then you should send an explicit disconnect event to let the server know. Check out Client:disconnect or Client:disconnectLater. Using those methods should disconnect faster, because it is explicit.

prashantgupta24 commented 3 years ago

Thanks for replying @camchenry ! That totally makes sense.

For future reference, those that are using love2d can add something like this to their client code:

function love.quit()
  print("Thanks for playing!")
  client:disconnectNow()
end

This will ensure the disconnect message is sent immediately.

prashantgupta24 commented 3 years ago

@camchenry do you have a way of figuring out which client got disconnected? One obvious way is to associate a unique ID with each client. I tried using the client:getConnectID, but the issue is that with:

function love.quit()
  print("Thanks for playing!")
  client:disconnectNow()
end

and

server:on("disconnect", function(data, client)

the client:getConnectID() returns 0.

I tried passing the ConnectID as code to disconnectNow, but if the connect ID is greater than 2147483648 it caps it to that number.

Is there a better way?

Workaround

As a workaround for now, I've attached a field called uniqueID to the client object itself when it connects to the server:

client.uniqueID = client:getConnectId()

This is present when the call to disconnect happens, which allows me to know which client got disconnected.

Let me know if that's the best way to deal with this or am I missing something?

camchenry commented 3 years ago

@prashantgupta24 Instead of getConnectID, try using Client:getIndex(), which returns an index associated with the client (which should be unique per client per connection). You will very likely have to keep a hash table which maps the client index to the user information. For example, mapping client index to username, stats, etc.

clientIndex[0] = { ... user 1 data ... }
clientIndex[1] = NIL
clientIndex[2] = { ... user 3 data ... }
clientIndex[3] = { ... user 2 data ... }

There will be some bookkeeping involved on the connect and disconnect events for managing this table, e.g., create a new entry when a client connects and clear it out / mark as inactive when they disconnect.

prashantgupta24 commented 3 years ago

Thanks @camchenry !