Last Updated: 8/30/2022, 10:56:05 AM

# Session Browser

# Overview

AccelByte offers a session browser feature to store your game session data. This browser supports P2P sessions to store game clients and a Dedicated Server to store game server sessions. Both P2P and Dedicated Server sessions use REST API for the game client and server.

# P2P

P2P sessions are generated by a game client and act as a session host. P2P entries contain game client session data which are stored in the session browser. When the lobby is disconnected, the P2P entries are removed from the server. If the lobby connection is reconnected by the host, past P2P entries will not be listed in the server browser and must be recreated in the session browser.

# Dedicated Server (DS)

A Dedicated Server session is a session generated by the server that is managed by Armada.

  • If the server is managed by Armada, the Session browser will listen to events broadcast from our Dedicated Server Manager Controller (DSMC) and Matchmaking service. The game’s Dedicated Server (DS) only needs to interact with those services, and so the data in the session browser is automatically updated.
  • If the server is not managed by Armada, we provide REST APIs in our SDK so the DS session can also be managed via the session browser, even if the DS is not managed with Armada.

# Permissions

Permissions are used to grant access to specific resources within our services. Make sure your account has the following permissions before you attempt to manage the Session Browser.

Usage Resource Action
Create Session NAMESPACE:{namespace}:SESSIONBROWSER:SESSION Create
Retrieve List of Game Sessions ADMIN:NAMESPACE:{namespace}:SESSIONBROWSER:SESSION Read
Retrieve Game Session by Session ID ADMIN:NAMESPACE:{namespace}:SESSIONBROWSER:SESSION Read
Update Session NAMESPACE:{namespace}:SESSIONBROWSER:SESSION Update
Delete Session NAMESPACE:{namespace}:SESSIONBROWSER:SESSION Delete
Join Session NAMESPACE:{namespace}:SESSIONBROWSER:SESSION Read
Register Player to Session NAMESPACE:{namespace}:SESSIONBROWSER:SESSION Update
Unregister Player to Session NAMESPACE:{namespace}:SESSIONBROWSER:SESSION Update
Get Recent Player Data NAMESPACE:{namespace}:SESSIONBROWSER:RECENTPLAYER Read

Permissions work slightly differently depending on whether they are assigned to IAM Clients or on Roles assigned to users. For more information, see AccelByte’s Authentication and Authorization documentation.

# Prerequisites

  • Make sure you’ve downloaded and configured AccelByte’s Unreal Engine SDK.
  • Log in as a user in Game Client if you want to implement a session browser in the game client.
  • Log in with game client credentials if you want to implement a session browser in the game server.

# Call the Session Browser

# Game Client

You can call the session browser from the Game Client using the following function:

FApiClientPtr ApiClient { FMultiRegistry::GetApiClient() };
ApiClient->SessionBrowser

# Game Server (Dedicated Server)

You can call the session browser from the Dedicated Server using the following function:

FServerApiClientPtr ServerApiClient{ FMultiRegistry::GetServerApiClient() };

ServerApiClient->ServerSessionBrowser

# Implementing Session Browser with the SDK

# Create a Session

Call the CreateGameSession() function to create a new session. Make sure you specify the EAccelByteSessionType parameter as dedicated if you want to create a Dedicated Server session, or p2p to create a P2P session.

# Retrieve a List of Game Sessions

Call the SessionBrowser.GetGameSessions() function to retrieve a list of active game sessions. Make sure you specify the EAccelByteSessionType parameter as dedicated if you want to retrieve a list of Dedicated Server sessions, or p2p to list P2P sessions.

# Retrieve a Game Session by Session ID

Call the SessionBrowser.GetGameSessions() function to retrieve a specific game session. Make sure you specify the EAccelByteSessionType parameter as dedicated if you want to retrieve a Dedicated Server session, or p2p to list P2P sessions.

# Update a Session

Call the UpdateGameSession() function to keep the ongoing session’s player count updated in real-time.

# Delete a Session

Call the RemoveGameSession() function to delete a session.

# Join a Session

Call the JoinSession() function to join a known session. This method requires a session ID and password (if the session has a password). This function will return network data such as IP and Port that can be used to connect to a game host.

# Register Player to Session

When the game host detects that a player has joined a session, the RegisterPlayer() function will be called to update the session data with the new player.

# Unregister Player to Session

When the game host detects that a player has left a session, the UnegisterPlayer() function will be called to remove the player from the session data.

# Get Recent Player Data

Call the GeRecentPlayer() function to retrieve information such as userID and displayName from recently encountered players.

# Create Game Sessions without Matchmaking

There are two options for creating game sessions without using Matchmaking:

  • You can create a host for your own private session which uses the session browser to create a session and request a dedicated server for that session, or
  • You can enable the DS to create an open session which is open for players to join when they browse for available sessions in the lobby.

# Create a Private Session

In a private session, the user commands the host to create a session which players can then be invited to join. The host requests a dedicated server for this session.

To understand how private sessions work, you will need to know how the session browser works in AccelByte Cloud’s backend services. The flowchart below illustrates this process. The first step involves creating a new game session, spawning a new server from the DSM, and retrieving the server address information from the client when the server is busy. The client can then travel to the server using the server address information after retrieving lobby notifications from the DS.

lobby

  1. Use the following function to create a game session: FRegistry::SessionBrowser.CreateGameSession("NewGameSessionName", <successDelegate>, <errorDelegate>) function.

  2. Check if the lobby is connected by calling FRegistry::Lobby.IsConnected(). If it is connected, then call FRegistry::Lobby.SetDsNotifDelegate(). This function will subscribe to the delegate whether your server status is ready or not.

  3. Call FRegistry::Lobby.RequestDS(ResultGameSession.Session_id, "gamemodetest", "", "", "default"); to start requesting a dedicated server from the pod. Wait until the server is ready to call back before proceeding to the next step.

  4. After receiving a response from the DS, the lobby will retrieve the data as we define using ResultDSNotice models data.

  5. Check the server status by calling ResultDSNotice.status. If the server is BUSY, then we can start to travel to the server using ResultDSNotice.Ip and ResultDSNotice.Port.

FULL CODE
FString SessionTypeString = FAccelByteUtilities::GetUEnumValueAsString(EAccelByteSessionType::dedicated);
FAccelByteModelsSessionBrowserCreateRequest NewGameSession;
NewGameSession.Username = FRegistry::Credentials.GetUserDisplayName();
NewGameSession.Namespace = FRegistry::Credentials.GetNamespace();
NewGameSession.Session_type = SessionTypeString;
NewGameSession.Game_session_setting.Mode = "gamemodetest";
NewGameSession.Game_session_setting.Map_name = "NewGameMapName";
NewGameSession.Game_session_setting.Num_bot = 0;
NewGameSession.Game_session_setting.Max_player = 12;
NewGameSession.Game_session_setting.Current_player = 0;
NewGameSession.Game_session_setting.Max_internal_player = 0;
NewGameSession.Game_session_setting.Current_internal_player = 0;
NewGameSession.Game_session_setting.Password = "";
NewGameSession.Game_version = "0.0.7.test";
 
FRegistry::SessionBrowser.CreateGameSession(NewGameSession, THandler<FAccelByteModelsSessionBrowserData>::CreateWeakLambda(this, [this](const FAccelByteModelsSessionBrowserData& ResultGameSession)
{
   if (FRegistry::Lobby.IsConnected())
   {
      FRegistry::Lobby.SetDsNotifDelegate(AccelByte::Api::Lobby::FDsNotif::CreateWeakLambda(this, [this, ResultGameSession](const FAccelByteModelsDsNotice& ResultDSNotice)
      {
         if (ResultDSNotice.Status == "BUSY")
         {
            const FString SessionAddress = FString::Printf(TEXT("%s:%d"), *ResultDSNotice.Ip, ResultDSNotice.Port);
            GetWorld()->GetFirstPlayerController()->ClientTravel(SessionAddress, TRAVEL_Absolute);
         }
      }));
 
      FRegistry::Lobby.RequestDS(ResultGameSession.Session_id, "gamemodetest", "", "", "default");
   }
}), FErrorHandler::CreateWeakLambda(this, [](int32 ErrorCode, const FString& ErrorMessage)
{
   // On Error Create Game Session
}));

# Query and Join a Game Session

To understand how joining private sessions works, you will need to know how the session browser works in AccelByte Cloud’s backend services. This involves the game client querying the sessions browser, finding, and joining a session. The flowchart below illustrates this process.

lobby

  1. Use the following function to retrieving all the available game sessions: FRegistry::SessionBrowser.GetGameSessions(EAccelByteSessionType::dedicated, "Game Mode", <successDelegate>, <errorDelegate>). The success delegate will retrieve the model FAccelByteModelsSessionBrowserGetResult. In this case, we want to join the server session when the game version is not empty, so the session type is dedicated and its joinable status is true.

  2. Join the server session by calling SessionBrowserData.Game_version.IsEmpty(), SessionBrowserData.Session_type, and SessionBrowserData.Joinable.

    If the response is successful, it will retrieve model data that represents the IP address and port of the game session.

  3. Use the following function to travel to the server using the server address: const FString SessionAddress = FString::Printf(TEXT("%s:%d"), *Result.Server.Ip, Result.Server.Port); GetWorld()->GetFirstPlayerController()->ClientTravel(SessionAddress, TRAVEL_Absolute);.

FULL CODE
FRegistry::SessionBrowser.GetGameSessions(EAccelByteSessionType::dedicated, "", THandler<FAccelByteModelsSessionBrowserGetResult>::CreateWeakLambda(this, [this](const FAccelByteModelsSessionBrowserGetResult& Result)
{
   for (const FAccelByteModelsSessionBrowserData SessionBrowserData : Result.Sessions)
   {
      if (!SessionBrowserData.Game_version.IsEmpty() && SessionBrowserData.Session_type == "dedicated" && SessionBrowserData.Joinable == true)
      {
         const FString SessionBrowserPassword = "";
         FRegistry::SessionBrowser.JoinSession(SessionBrowserData.Session_id, SessionBrowserPassword, THandler<FAccelByteModelsSessionBrowserData>::CreateWeakLambda(this, [this](const FAccelByteModelsSessionBrowserData& Result)
         {
            const FString SessionAddress = FString::Printf(TEXT("%s:%d"), *Result.Server.Ip, Result.Server.Port);
            GetWorld()->GetFirstPlayerController()->ClientTravel(SessionAddress, TRAVEL_Absolute);
         }), FErrorHandler::CreateWeakLambda(this, [](int32 ErrorCode, const FString& ErrorMessage)
         {
            // On Join Session Error        
         }));
 
         break;
      }
   }
}), FErrorHandler::CreateWeakLambda(this, [](int32 ErrorCode, const FString& ErrorMessage)
{
   // On Get Game Sessions Error
}));

# Register a Player

After joining or traveling to the server, you will need to assign some logic inside the server to register a new player to the session.

  1. Call InitNewPlayer and override it from the game mode base function. From this function, you can get a new player controller and some options that can be used for parsing the player id.

  2. Parse the player id from the Options parameter using UGameplayStatics::ParseOption(Options, "PlayerId").

  3. Check if the current session/server of the match id is empty by calling FRegistry::ServerCredentials.GetMatchId().IsEmpty().

  4. If the match id is empty, then get the session by calling FRegistry::ServerDSM.GetSessionId(<successDelegate>, <errorDelegate>). After the response is successful, you will receive the model data. Use Result for the proceeding steps.

  5. Set the match id using FRegistry::ServerCredentials.SetMatchId(Result.Session_id).

  6. Call PostInitPlayer() to pass our player id and player controller data. Inside PostInitPlayer(), call FRegistry::SessionBrowser.RegisterPlayer(FRegistry::ServerCredentials.GetMatchId(), ParsedPlayerId, false /*not a spectator*/, <successDelegate>, <errorDelegate>).

FULL CODE
FString AAccelByteGameMenuGM::InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueNetId, const FString& Options, const FString& Portal)
{
  const FString ParsedPlayerId = UGameplayStatics::ParseOption(Options, TEXT("PlayerId"));
 
   if (FRegistry::ServerCredentials.GetMatchId().IsEmpty())
   {
      FRegistry::ServerDSM.GetSessionId(THandler<FAccelByteModelsServerSessionResponse>::CreateWeakLambda(this, [this, ParsedPlayerId, NewPlayerController](const FAccelByteModelsServerSessionResponse& Result)
      {
         FRegistry::ServerCredentials.SetMatchId(Result.Session_id);
 
         PostInitPlayer(ParsedPlayerId, NewPlayerController);
      }), FErrorHandler::CreateWeakLambda(this, [ParsedPlayerId, NewPlayerController](int32 ErrorCode, const FString& ErrorMessage)
      {
         // On Error Get Session      
      }));
   }
   else   {
      PostInitPlayer(ParsedPlayerId, NewPlayerController);
   }
 
  return Super::InitNewPlayer(NewPlayerController, UniqueNetId, Options, Portal);
}
 
void AAccelByteGameMenuGM::PostInitPlayer(const FString& ParsedPlayerId, APlayerController* PlayerController)
{
   FRegistry::ServerSessionBrowser.RegisterPlayer(FRegistry::ServerCredentials.GetMatchId(), ParsedPlayerId, false, THandler<FAccelByteModelsSessionBrowserAddPlayerResponse>::CreateWeakLambda(this, []()
   {
      // On Register Player Success   }), AccelByte::FErrorHandler::CreateWeakLambda(this, [](int32 ErrorCode, const FString& ErrorMessage)
   {
      // On Register Player Error  
   }));
}

# Create an Open Session

WARNING

For the following steps, you will need to be running Unreal SDK Plugin v12.1.2 and AccelByte Cloud Version v3.23.4 or higher.

You can set the DS to create its own game sessions which can be left open for players to join when browsing available sessions.

First, you will need to know how the session browser works with our backend services.

lobby

This diagram shows how the DS registers and creates its own session in the DSMC. By doing this, the DS doesn’t need to wait for the session Id from the players’ matchmaking data and can therefore be queried and join directly via the session browser.

  1. Spawn a server as a buffer in the DSM in the Admin Portal.

    TIP

    See our AccelByte Cloud Armada documentation (opens new window) to learn how to spawn a server as a buffer with dedicated server managers in the Admin Portal.

  2. Use the following code to allow the DS to log in using client credentials.

    FServerApiClientPtr ServerApiClient = FMultiRegistry::GetServerApiClient();
    
    ServerApiClient->ServerOauth2.LoginWithClientCredentials(FVoidHandler::CreateLambda([&]()
    {
      // do something on server login success
    }), FErrorHandler::CreateLambda([&](int32 ErrorCode, FString ErrorMessage)
    {
      // do something on server login failed
    }));
    
  3. Use the following code to allow the DS to register to Armada.

     ServerApiClient->ServerDSM.RegisterLocalServerToDSM("127.0.0.1", 7777, ServerName, FVoidHandler::CreateLambda([&]()
    {
       // do something on register server success
    }), FErrorHandler::CreateLambda([&](int32 ErrorCode, FString ErrorMessage)
    {
       // do something on register server failed
    }));
    
  4. Use the following code to allow the DS to create a game session via the session browser.

    NOTE

    Your OAuth client will need the permission NAMESPACE:{namespace}:SESSIONBROWSER:SESSION with the Create action. Follow this guide (opens new window) to enable this permission on your OAuth client.

    ServerApiClient->ServerSessionBrowser.CreateGameSession(
    EAccelByteSessionType::dedicated // session type must be dedicated
    , "GameMode"  // the intended game mode
    , "GameMap"   // the game's map name
    , "GameVersion" // the game server's version
    , 1           // maximum bot number
    , 8           // maximum player
    , 4           // maximum spectator
    , "Password"  // the session's password
    , SettingJson // other server settings that game clients need to know
    , THandler<FAccelByteModelsSessionBrowserData>::CreateLambda([&](FAccelByteModelsSessionBrowserData const& Data)
       {
          // do something on create game session success
       })
    , FErrorHandler::CreateLambda([&](int32 ErrorCode, FString ErrorMessage)
       {
          // do something on create game session failed
       }));
    
  5. Use the following code to allow the DS to register a session to the DSMC via the DSMC Create Session Endpoint (opens new window).

NOTE

Your OAuth client will need the permission NAMESPACE:{namespace}:DSM:SESSION with the Create action. Follow this guide (opens new window) to enable this permission on your OAuth client.

ServerApiClient->ServerDSM.RegisterServerGameSession(
     GameSession.Session_id, // the created game session id from step 3
     GameMode, // the intended game mode
   THandler<FAccelByteModelsServerCreateSessionResponse>::CreateLambda(
   [&](const FAccelByteModelsServerCreateSessionResponse& Result)
   {
      // Do something after game session registered
   }), FErrorHandler::CreateLambda([&](int32 ErrorCode, FString ErrorMessage)
     {
         // do something after game session registration failed
     }));
  1. Use the following code to allow the game clients to find sessions via the session browser.

       TestSessionBrowserApiClients[0]->SessionBrowser.GetGameSessions(
    EAccelByteSessionType::dedicated
    , "GameMode"
    , THandler<FAccelByteModelsSessionBrowserGetResult>::CreateLambda([&](const FAccelByteModelsSessionBrowserGetResult& Result)
       {
          // do something on get game session success
       }), FErrorHandler::CreateLambda([&](int32 ErrorCode, FString ErrorMessage)
       {
          // do something on get game session failed
       }));
    
  2. Use the following code to allow the game clients to join sessions via the session browser and retrieve server data such as IP addresses and ports.

       TestSessionBrowserApiClients[0]->SessionBrowser.JoinSession(
    GameSession.Session_id // game's session Id, acquired from step 5 (GetSessions)
    , "" // the session's password
    , THandler<FAccelByteModelsSessionBrowserData>::CreateLambda([&](const FAccelByteModelsSessionBrowserData& Result)
       {
          bJoinDone = true;
          JoinResult = Result;
       }), SessionBrowserTestErrorHandler);
    

# Connect Custom Services to the Session Browser using the Server SDKs

# SDK Initialization

Before using the Session Browser service, you must initialize your server-side SDK to be authorized to perform create, read, update, and delete actions.

# Golang SDK Initialization

To start using the Session Browser service from the Golang SDK, you must initialize the SDK by completing the following steps:

  • Create your OAuth Client and assign the necessary permissions to access the Achievement service.

  • Log in as a Client using the SDK.

  • Initialize the service using the following function:

    sessionService := &sessionbrowser.SessionService{
      Client:          factory.NewSessionBrowserClient(&repository.ConfigRepositoryImpl{}),
      TokenRepository: &repository.TokenRepositoryImpl{},
    }
    

Once you have successfully completed this initialization, you can use the Golang SDK to create, read, update, and delete Session Browsers from your serverless app.

# Python SDK Initialization

To start using the Session Browser service from the Python SDK, you must initialize the SDK by completing the following steps:

Once you have successfully completed this initialization, you can use the Python SDK to create, read, update, and delete Session Browsers from your serverless app.

# .NET (C#) SDK Initialization

Before using the Session Browser service, you will need to set some permissions. Use the following .NET namespaces:

using AccelByte.Sdk.Api.Sessionbrowser.Model;
using AccelByte.Sdk.Api.Sessionbrowser.Operation;
using AccelByte.Sdk.Api.Sessionbrowser.Wrapper;

# Java SDK Initialization

Before using the Session Browser service, you will need to set some permissions. Initialize the Session wrapper from the Session Browser service using the following code:

Session wSBSession = new Session(sdk);

Once completed, you can use the SDK to create, read, update, or delete sessions.

# Register a New Game Session

Use the following function to create a session (opens new window):

# Delete a Session

Use the following function to delete a session (opens new window) using the session ID:

# Retrieve a Session

Use the following function to retrieve a session (opens new window) using the session ID:

# Update a Session

Use the following function to update a session (opens new window). You can update a game session when you need to update the maximum number of players or number of current players in a session.