Friends

Finding Friends

FindFriends(userIds) asks the server for the current online and room status of the given user ids. It returns a Task<Result<std::vector<FriendInfo>>> with one entry per requested id.

Friends are identified purely by UserId, so friend queries only work when players authenticate with stable, known user ids. The SDK does not store a friend graph, who is friends with whom lives in your backend or platform service; the server only reports the live status of the ids you pass in.

Field Type Description
UserId StringType The id this entry describes.
IsOnline bool Whether the user is currently online.
RoomName StringType The room the user is in, empty when not in a room.
IsInRoom bool Whether the user is currently in a room.

Look up two friends and join the first one who is in a room:

C++
C

C++

Task<Result<void>> JoinAFriend(RealtimeClient& client)
{
    std::vector<RealtimeCore::Common::StringType> friendIds = {PHOTON_STR("erwin"), PHOTON_STR("theodor")};

    Result<std::vector<FriendInfo>> friends = co_await client.FindFriends(friendIds);
    if (friends.IsErr())
    {
        co_return Result<void>::Err(friends.GetError());
    }

    for (const FriendInfo& info : friends.GetValue())
    {
        if (info.IsInRoom)
        {
            Result<MutableRoomView> joined = co_await client.JoinRoom(info.RoomName);
            if (joined.IsErr())
            {
                co_return Result<void>::Err(joined.GetError());
            }
            co_return Result<void>::Ok();
        }
    }

    co_return Result<void>::Err(ErrorCode::RoomNotFound, PHOTON_STR("No friend is in a room right now"));
}

C

static const char* friendIds[] = {"erwin", "theodor"};

realtime_find_friends(client, friendIds, 2);

/* FindFriendsResult carries [int32 count] then, per friend,
   [string userId][u8 isOnline][string roomName][u8 isInRoom] */
if (e->type == RT_FindFriendsResult && e->mode == 0 && e->blobOffset >= 0)
{
    rt_reader r     = rt_read(blob + e->blobOffset, e->blobLength);
    int32_t   count = rt_get_i32(&r);

    for (int32_t i = 0; i < count; ++i)
    {
        int32_t     userIdLen = 0;
        (void)rt_get_str(&r, &userIdLen);
        (void)rt_get_u8(&r); /* isOnline */

        int32_t     roomLen = 0;
        const char* room    = rt_get_str(&r, &roomLen);
        uint8_t     inRoom  = rt_get_u8(&r);

        if (inRoom && roomLen > 0 && roomLen < 64)
        {
            /* The blob dies at the next flush, so copy the name before joining. */
            char name[64];
            memcpy(name, room, (size_t)roomLen);
            name[roomLen] = '\0';

            realtime_join_room(client, name, 0);
            break;
        }
    }
}

/* realtime_find_friends takes an array of null-terminated UTF-8 strings
   and its count. realtime_get_friend_list returns the same layout for the
   last result without a round trip, and realtime_get_friend_list_age
   reports its age in milliseconds. */

The Friend List

GetFriendList() returns the most recently fetched results without a server round trip, and GetFriendListAge() reports the age of that snapshot in milliseconds. Use the age to decide when a refresh warrants a new FindFriends() call instead of re-querying on every frame.

Back to top