> ## 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 du 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, lorsque 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 les éléments d'authentification des joueurs et les informations d'identification du serveur, cette mise en cache peut devenir gênante. 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 créés à l'aide de classes d'API statiques. Dans Unity, par exemple, vous pouvez voir une référence à **PlayFabClientAPI**. Ces classes statiques lisent et écrivent dans un état statique au sein du SDK. Leur dépendance à l'état statique rend leur utilisation difficile lorsque vous travaillez avec plusieurs joueurs au sein du même client de jeu. Les classes d'API instanciées évitent ces problèmes, en contrepartie d'exigences accrues de gestion et de suivi de votre part. Si 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 similaire. 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 ne disposez peut-être pas encore du contexte d'authentification d'un joueur. Dans ce cas, il vous suffit de fournir des paramètres de base, comme un ID de titre. Ces paramètres sont transmis via 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és, elle peut être utilisée de la même manière qu'une classe statique. Tous les objets de requête 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 simple de gérer ces instances en les encapsulant derrière un objet joueur qui en est le propriétaire, mais ce choix vous appartient.

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

## Exemple Unity

Cet exemple de code montre comment plusieurs joueurs peuvent se connecter à un jeu et disposer d'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** simplifié. Au démarrage du jeu, nous connectons deux joueurs, puis nous récupérons les données stockées dans PlayFab pour chacun d'eux.

```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 présente un acteur dans Unreal qui contient son propre contexte de connexion PlayFab. Il montre comment encapsuler des classes d'instance d'API PlayFab au sein d'une classe **ALoginActor**. Plusieurs instances d'**ALoginActor** peuvent être ajoutées à une carte, recevoir leurs propres CustomIds et effectuer des opérations PlayFab de manière 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 serveur

De la même manière 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, voire 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. Sur un serveur, cette API est généralement **PlayFabAuthenticationInstanceAPI.GetEntityToken**. Comme pour la connexion d'un 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 via la propriété d'instance **authenticationContext**.


## Related topics

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