Skip to content

Update friend presence #50

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

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft

Update friend presence #50

wants to merge 1 commit into from

Conversation

Indexu
Copy link

@Indexu Indexu commented Oct 14, 2021

We would like to somehow update the presence of players' friends when they go online/offline.

Initial implementation:

  • Update online

    1. Client registers itself with Drift
    2. Client later makes a friends playergroup which includes all the player ids
    3. Hook into the event when the playergroup is created
    4. Fetch all players in the created friends playergroup from db that have a registered active, non-heartbeat-timeout client
    5. Post message to those players that the player has come online
  • Update offline

    1. Client deregisters
    2. Hook into the event when the client is deregistered
    3. Fetch the friends playergroup for the exiting player
    4. Same as above, fetch the players in the group with same criteria
    5. Post offline message to those players

Issues:

  • Whenever the client calls LoadDriftFriends the friends playergroup is created/updated/set and fires the event online event/message again
    • Receiving clients can deduce whether or not to broadcast the OnFriendsPresenceChanged delegate by comparing their locally cached state and see if the presence really changed
    • Can also be solved via using the friend messaging system
      • When a player comes online and has populated his local friends list, send the online message to players in the local friends list
  • Doesn't handle ungraceful exits (crash, d/c, etc...)
    • One idea is to utilize the client heartbeat
      • When a client heartbeats, fetch all the player's online friends and check their client heartbeat timeout
      • Not sure of the performance impact this might have

@Indexu
Copy link
Author

Indexu commented Oct 14, 2021

@judgeaxl How do the external friend ids work?

I noticed in the C++ client code that the friends playergroup is created via the Drift friendships and external auth provider ids.

Is there any way for Drift to know the requesting player's external friend ids?
If so, I might get away with not using the friends playergroup, it feels kind of hacky to use it in this way.

@judgeaxl
Copy link

judgeaxl commented Oct 15, 2021

The player group was yet another time-to-market "hack" we'd rather forget about. Basically allowing the client to say "here's a group of players I want to treat as a group", and after that there are some endpoints which accept a group name instead of a list of player IDs.

Before we had native friends support in drift-base, we relied on external friends, so we'd look up the list of Steam friends a player had, through the Steam API, and then we'd match those against player identities to find Drift IDs for the same players. You'd then get back a list of Drift IDs for any Steam friends who had ever played the game too. Essentially, "hey, I've got these Steam friends, can you check them for me, and call them my_friends?". Sure, the server says, I recognize these two, here's drift-base player info for them. You can refer to them as "my_friends" where you otherwise would send a list of player IDs.

I'm not sure how useful this ever was, but it was better than having no way of connecting with other players.

@judgeaxl
Copy link

As for presence, the client is the main "session" record we have. It's reasonable that the Friends API listens to added and removed clients and generates updates for the friends of players. IMO this should use the friendships API rather than player groups, but there's no real constraint other than player groups being a bit of a hack as mentioned above.

When querying for client records they have a pseudo property saying if they're online or not, based on the last heartbeat. This obviously lags a bit, if the client crashes, but presence notifications should probably expire rather quickly. Listening for post/delete to clients (via the message bus, as is already done, just not hooked up to anything) would be the place for initiating the notifications when a client is created or deleted.

To discover and propagate notifications on clients timing out is harder, unless we add a worker which can go over all clients and message friends of those who have timed out with some interval.

@judgeaxl
Copy link

We should have a general chat about what presence means in terms of many different systems.

Is it a notification system between friends only?
Do we want to maintain the external friends, or just "real" drift-base friends?
Should a timeout-worker cover notifications for lobbies and parties, or would they need their own workers? How to avoid that this worker doesn't do double work when we have many instances?
How would such a worker be implemented? As a local gevent worker per instance? As separate deployables running in "worker mode"? Using leader election?

Are there patterns which would generate an excessive amount of notifications?

@Indexu
Copy link
Author

Indexu commented Oct 15, 2021

I'm not familiar with the external auth flow in Drift.
Does Drift act as a proxy to auth with external providers or is it client only?

@judgeaxl
Copy link

I'm not familiar with the external auth flow in Drift. Does Drift act as a proxy to auth with external providers or is it client only?

The client asks the local provider, Steam, Game Center or other, for credentials which allow the backend to validate the user, which is usually done either through a JWT validation, or through some API that the backend calls out to. We never trust the client implicitly when it says "Hey, I'm user XYZ on Steam".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants