> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Gestion de plusieurs connexions PlayFab

> Utilisez les classes d'API instanciées des SDK PlayFab pour gérer plusieurs connexions de joueurs simultanées à partir d'un seul client ou serveur sans conflit d'état statique.

Par défaut, la plupart des SDK PlayFab mettent en cache les résultats de connexion des joueurs. Cette mise en cache peut être pratique dans le scénario le plus courant, où vous attendez la connexion d'un seul joueur. Dans les jeux qui prennent en charge plusieurs joueurs simultanés, ou sur les serveurs où vous gérez à la fois le matériel d'authentification des joueurs et les informations d'identification du serveur, cette mise en cache peut devenir un obstacle. Pour faciliter ces scénarios, les SDK PlayFab contiennent à la fois des classes d'API statiques et des classes d'API instanciées.

## Classes d'API statiques et classes d'API instanciées

La plupart des exemples et des exemples de code pour PlayFab sont conçus à l'aide de classes d'API statiques. Dans Unity, par exemple, vous pourriez voir une référence à **PlayFabClientAPI**. Ces classes statiques écrivent dans un état statique au sein du SDK et lisent à partir de celui-ci. Leur dépendance à l'état statique rend difficile l'utilisation de ces classes lorsque vous travaillez avec plusieurs joueurs dans le même client de jeu. Les classes d'API instanciées évitent ces problèmes, en échange d'exigences accrues de gestion et de suivi de votre part. Dans les cas où vous devez prendre en charge plusieurs connexions PlayFab simultanées, nous vous recommandons d'utiliser des classes d'API instanciées.

Dans le SDK Unity, **PlayFabClientInstanceAPI** est la version instanciée de **PlayFabClientAPI**. Toutes les autres classes d'API suivent un modèle de nommage semblable. Lorsque vous utilisez la version instanciée d'une classe d'API, vous devez créer une instance de la classe avant de pouvoir appeler des méthodes. Pour créer une instance, vous devez spécifier un contexte supplémentaire. Pour la plupart des classes, le contexte supplémentaire requis est simplement le contexte d'authentification du joueur. Dans Unity, ce contexte est **PlayFabAuthenticationContext**. Certaines classes contiennent des appels de connexion. Pour ces appels, vous n'avez peut-être pas encore de contexte d'authentification du joueur. Si c'est le cas, vous devez seulement fournir des paramètres de base comme un ID de titre. Ces paramètres sont transmis au moyen d'un objet **PlayFabApiSettings**.

## Utilisation des classes d'API instanciées

Une fois que vous avez créé une classe d'API instanciée avec un contexte d'authentification ou un objet de paramètres d'API approprié, vous pouvez l'utiliser de la même façon qu'une classe statique. Tous les objets de demande et de réponse sont identiques. La seule différence est que vous êtes responsable du suivi de la durée de vie de l'instance et que vous devez vous assurer que tous les appelants potentiels de PlayFab reçoivent une instance appropriée. Lorsque vous gérez plusieurs joueurs, vous avez besoin de plusieurs instances de chaque classe d'API, une par joueur. Il est souvent plus facile de gérer ces instances en les encapsulant derrière un objet joueur qui en est le propriétaire, mais ce choix vous revient.

Les classes instanciées qui connectent un joueur (comme **PlayFabClientInstanceAPI**) créent et mettent également en cache le contexte d'authentification de ce joueur dans l'instance de la classe d'API. Cette fonctionnalité vous permet de référencer facilement le contexte d'authentification lorsque vous créez les autres classes dont vous avez besoin.

## Exemple Unity

Cet exemple de code montre comment plusieurs joueurs peuvent se connecter à un jeu et avoir un état indépendant suivi dans des instances de classe distinctes. Dans cet exemple, les classes d'API et les fonctionnalités de base sont encapsulées derrière un objet **PlayFabPlayer** simpliste. Lorsque le jeu démarre, nous connectons deux joueurs, puis nous obtenons toutes les données stockées dans PlayFab pour chacun de ces joueurs.

```csharp theme={null}
using PlayFab;
using PlayFab.ClientModels;
using PlayFab.DataModels;
using System.Collections.Generic;
using UnityEngine;

public class PlayFabLogin : MonoBehaviour
{
    PlayFabPlayer player1 = new PlayFabPlayer();
    PlayFabPlayer player2 = new PlayFabPlayer();

    // Start is called before the first frame update
    void Start()
    {
        if (string.IsNullOrEmpty(PlayFabSettings.staticSettings.TitleId))
        {
            // Please change the titleId below to your own titleId from PlayFab Game Manager.
            PlayFabSettings.staticSettings.TitleId = "";
        }

        player1.Login("testLogin1");
        player2.Login("testLogin2");
    }

    // Update is called once per frame
    void Update()
    {
        if (player1.loggedIn && !player1.dataLoaded && !player1.dataLoading)
        {
            player1.LoadData();
        }
        if (player2.loggedIn && !player2.dataLoaded && !player2.dataLoading)
        {
            player2.LoadData();
        }
    }
}

class PlayFabPlayer
{
    public bool loggedIn = false;
    public bool dataLoading = false;
    public bool dataLoaded = false;
    public string PlayFabId;
    public Dictionary<string, ObjectResult> playerData;

    private PlayFabClientInstanceAPI clientApi;
    private PlayFabDataInstanceAPI dataApi;

    public void Login(string customId)
    {
        clientApi = new PlayFabClientInstanceAPI(PlayFabSettings.staticSettings);

        var request = new LoginWithCustomIDRequest { CustomId = customId, CreateAccount = true };

        clientApi.LoginWithCustomID(request, result =>
        {
            PlayFabId = result.PlayFabId;
            loggedIn = true;
            dataApi = new PlayFabDataInstanceAPI(clientApi.authenticationContext);
            Debug.Log("Login call succeeded.");
        }, error =>
        {
            Debug.LogWarning("Something went wrong with the login call.");
            Debug.LogError("Here's some debug information:");
            Debug.LogError(error.GenerateErrorReport());
        });
    }

    public void LoadData()
    {
        dataLoading = true;
        var request = new GetObjectsRequest { Entity = new PlayFab.DataModels.EntityKey { Id = clientApi.authenticationContext.EntityId, Type = clientApi.authenticationContext.EntityType } };

        dataApi.GetObjects(request, result =>
        {
            playerData = result.Objects;
            dataLoaded = true;
            dataLoading = false;
            Debug.Log("Player data loaded.");
        }, error =>
        {
            Debug.LogWarning("Something went wrong with the GetObjects call.");
            Debug.LogError("Here's some debug information:");
            Debug.LogError(error.GenerateErrorReport());
        });
    }
}
```

## Exemple Unreal

Cet exemple de code montre un acteur dans Unreal qui contient son propre contexte de connexion PlayFab. Il montre comment encapsuler les classes d'instance de l'API PlayFab dans une classe **ALoginActor**. Plusieurs instances d'**ALoginActor** peuvent être ajoutées à une carte, recevoir leurs propres CustomIds et effectuer des opérations PlayFab de façon indépendante.

LoginActor.h :

```cpp theme={null}
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "PlayFab.h"
#include "Core/PlayFabError.h"
#include "Core/PlayFabClientDataModels.h"
#include "Core/PlayFabClientAPI.h"
#include "Core/PlayFabDataAPI.h"
#include "LoginActor.generated.h"

UCLASS()
class MINUE_PF_MARKET_API ALoginActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ALoginActor();

    // Please change the TitleId below to your own TitleId from PlayFab Game Manager.
	UPROPERTY(EditAnywhere, config, Category = Settings)
	FString TitleId = TEXT("");

	UPROPERTY(EditAnywhere, config, Category = Settings)
	FString CustomId = TEXT("ExampleCustomId");

protected:
	// Called when the game starts or when spawned

	virtual void BeginPlay() override;

	void OnLoginSuccess(const PlayFab::ClientModels::FLoginResult& Result);
	void OnGetObjectsSuccess(const PlayFab::DataModels::FGetObjectsResponse& Result);
	void OnError(const PlayFab::FPlayFabCppError& ErrorResult) const;

public:	
	bool LoggedIn = false;

	// Called every frame
	virtual void Tick(float DeltaTime) override;

	PlayFabClientPtr clientAPI = nullptr;
	PlayFabDataPtr dataAPI = nullptr;

	TMap<FString, PlayFab::DataModels::FObjectResult> PlayerData;
	bool DataLoaded = false;
};
```

LoginActor.cpp :

```cpp theme={null}
#include "LoginActor.h"

ALoginActor::ALoginActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
}

void ALoginActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

void ALoginActor::BeginPlay()
{
	Super::BeginPlay();
    GetMutableDefault<UPlayFabRuntimeSettings>()->TitleId = TitleId;

    clientAPI = IPlayFabModuleInterface::Get().GetClientAPI();
    dataAPI = IPlayFabModuleInterface::Get().GetDataAPI();

    PlayFab::ClientModels::FLoginWithCustomIDRequest request;
    request.CustomId = CustomId;
    request.CreateAccount = true; 

    clientAPI->LoginWithCustomID(request,
        PlayFab::UPlayFabClientAPI::FLoginWithCustomIDDelegate::CreateUObject(this, &ALoginActor::OnLoginSuccess),
        PlayFab::FPlayFabErrorDelegate::CreateUObject(this, &ALoginActor::OnError)
    );
}

void ALoginActor::OnLoginSuccess(const PlayFab::ClientModels::FLoginResult& Result)
{
    UE_LOG(LogTemp, Log, TEXT("Login call succeeded."));
    LoggedIn = true;

    PlayFab::DataModels::FGetObjectsRequest dataRequest;
    dataRequest.AuthenticationContext = Result.AuthenticationContext;
    dataRequest.Entity.Id = Result.EntityToken->Entity->Id;
    dataRequest.Entity.Type = Result.EntityToken->Entity->Type;

    dataAPI->GetObjects(
        dataRequest,
        PlayFab::UPlayFabDataAPI::FGetObjectsDelegate::CreateUObject(this, &ALoginActor::OnGetObjectsSuccess),
        PlayFab::FPlayFabErrorDelegate::CreateUObject(this, &ALoginActor::OnError)
    );
}

void ALoginActor::OnError(const PlayFab::FPlayFabCppError& ErrorResult) const
{
    UE_LOG(LogTemp, Error, TEXT("Something went wrong with your API call.\nHere's some debug information:\n%s"), *ErrorResult.GenerateErrorReport());
}

void ALoginActor::OnGetObjectsSuccess(const PlayFab::DataModels::FGetObjectsResponse& Result)
{
    PlayerData = Result.Objects;
    DataLoaded = true;
	UE_LOG(LogTemp, Log, TEXT("Player data loaded."));    
}
```

## Authentification du serveur

De la même façon que les classes d'API instanciées permettent à un client de jeu de gérer plusieurs joueurs, elles permettent aux serveurs de gérer une combinaison d'authentification de titre et de joueur, ou même plusieurs titres simultanément. Le modèle de base est presque identique. Instanciez une classe d'API pour gérer la connexion du serveur, fournissez à cette instance l'objet **PlayFabApiSettings** approprié, puis appelez une API d'authentification. Si vous êtes sur un serveur, cette API est généralement **PlayFabAuthenticationInstanceAPI.GetEntityToken**. Tout comme pour une connexion de joueur, le résultat d'un appel à **GetEntityToken** est mis en cache dans l'instance de la classe d'API et peut être référencé pour créer d'autres instances de classes d'API au moyen de la propriété d'instance **authenticationContext**.


## Related topics

- [Utilisation de plusieurs réseaux PlayFab Party](/fr-CA/services/playfab/multiplayer/networking/concepts-multiple-networks.md)
- [Notes de version de PlayFab Party](/fr-CA/services/playfab/multiplayer/networking/release-notes.md)
- [Notes de version du SDK PlayFab Services 2025](/fr-CA/services/playfab/release-notes/2025.md)
- [Pratiques exemplaires de consommation PlayFab](/fr-CA/services/playfab/pricing/consumption-best-practices.md)
- [Notes de publication PlayFab 2015](/fr-CA/services/playfab/release-notes/2015.md)
