> ## 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.

# Utilisation de PlayFab Party avec MPSD

> Combinez la mise en réseau vocale et de données de PlayFab Party avec le Multiplayer Session Directory (MPSD) XBOX pour la gestion des sessions et des invitations entre réseaux.

Les scénarios multijoueurs XBOX s'appuient sur le service Multiplayer Session Directory (MPSD) et sur les documents MPSD. Les documents MPSD font office de liste des participants de votre session de jeu actuelle et pilotent les expériences multijoueurs telles que le matchmaking, les invitations de plateforme, les listes de joueurs récents et la jonction en cours de partie.

Ce document décrit comment intégrer PlayFab Party dans les flux multijoueurs courants qui nécessitent MPSD.

Ce document ne propose pas d'analyse approfondie de MPSD et de toutes ses fonctionnalités. Pour plus d'informations, consultez la [documentation MPSD](/fr/services/xbox-services/multiplayer/mpsd/live-mpsd-overview).

## Matchmaking

Voici un flux simplifié qui montre comment utiliser le matchmaking et MPSD avec PlayFab Party :

1. Les joueurs créent des sessions MPSD et s'y rassemblent ; ces sessions représentent les groupes qui souhaitent jouer ensemble d'une session de matchmaking à l'autre. Les joueurs se rassemblent dans ces sessions à l'aide des fonctionnalités d'invitation et de jonction de XBOX.

2. Ces groupes de joueurs soumettent des tickets au service de matchmaking, qui rassemble les groupes de joueurs compatibles dans une session de matchmaking. Cette session de matchmaking est elle-même représentée par un nouveau document de session que les joueurs rejoignent ensuite. Les joueurs doivent également écouter les modifications apportées à ce document de session.

3. Une fois la session de matchmaking finalisée et la liste des participants verrouillée, le titre doit désigner l'un des membres de la session de matchmaking pour configurer le réseau PlayFab Party. Une stratégie simple pour sélectionner le créateur du réseau Party consiste à utiliser le premier membre du document de session MPSD de matchmaking.

4. Le membre sélectionné crée le réseau avec une `PartyInvitation` initiale qui limite l'accès au réseau aux seuls membres de la session de matchmaking. Une fois la création du réseau terminée avec succès, le membre sélectionné doit publier le descripteur de réseau et l'invitation Party obtenus dans le document de session, sous forme de propriété de session, afin que les autres membres puissent les utiliser.

   ```cpp theme={null}
   void
   OnMatchmakingSessionFinalized(
       uint32_t usersInSessionCount,
       const uint64_t* usersInSession
       )
   {
       PartyInvitationConfiguration initialInvite{};
       initialInvite.identifier = nullptr; // let Party select the invitation identifier for simplicity
       initialInvite.revocability = PartyInvitationRevocability::Anyone; // must be revocable by anyone

       // the updated invite should contain all users in the matchmaking session
       std::vector<PartyString> entityIdsInSession;
       for (uint32_t i = 0; i < usersInSessionCount; ++i)
       {
           uint64_t xboxUserId = usersInSession[i];
           // Call title-defined xuid->entityid mapping helper
           PartyString xboxUserEntityId = GetEntityIdFromXboxUserId(xboxUserId);
           if (xboxUserEntityId != nullptr)
           {
               entityIdsInSession.push_back(xboxUserEntityId);
           }
           else
           {
               DEBUGLOG("User %llu did not have a matching entity ID.", xboxUserId);
           }
       }
       initialInvite.entityIdCount = entityIdsInSession.size();
       initialInvite.entityIds = entityIdsInSession.data();

       // This is an asynchronous call. It will be completed when StartProcessingStateChanges generates a
       // PartyCreateNewNetworkCompletedStateChange struct
       PartyError error = PartyManager::GetSingleton().CreateNewNetwork(
           m_localPartyUser,
           &networkConfiguration,
           0,
           nullptr,
           &initialInvite,
           nullptr,
           nullptr,
           nullptr);
       if (FAILED(error))
       {
           DEBUGLOG("PartyManager::CreateNetwork failed! 0x%08x\n", error);
           return;
       }
   }

   void
   HandleCreateNewNetworkCompleted(
       const PartyCreateNewNetworkCompletedStateChange& createNewNetworkCompletedStateChange
       )
   {
       if (createNewNetworkCompletedStateChange.result == PartyStateChangeResult::Succeeded)
       {
           // The network was created successfully! Post the networks descriptor and invitation

           char serializedDescriptor[c_maxSerializedNetworkDescriptorStringLength + 1];
           PartyError error = PartyManager::SerializeNetworkDescriptor(
               &createNewNetworkCompletedStateChange.networkDescriptor,
               serializedDescriptor);
           if (PARTY_FAILED(error))
           {
               DEBUGLOG("PartyManager::SerializeNetworkDescriptor failed: 0x%08x\n", error);
               return;
           }

           UpdateSessionProperty(
               "PartyNetworkDescriptor", // arbitrary property name
               serializedDescriptor);

           UpdateSessionProperty(
               "PartyInitialInvitation", // arbitrary property name
               createNewNetworkCompletedStateChange.appliedInitialInvitationIdentifier);
       }
       else
       {
           // The network was not created successfully.
           // Please refer to CreateNewNetwork reference documentation for retry guidance
       }
   }
   ```

5. Lorsque chaque membre constate la mise à jour du document de session, il peut utiliser le descripteur de réseau et l'invitation pour se connecter au réseau et le rejoindre.

   ```cpp theme={null}
   void
   OnNetworkInformationPostedToSessionDocument(
       PartyString serializedNetworkDescriptor,
       PartyString invitationId
       )
   {
       PartyNetworkDescriptor networkDescriptor;
       PartyError error = PartyManager::DeserializeNetworkDescriptor(serializedNetworkDescriptor, &networkDescriptor);
       if (PARTY_FAILED(error))
       {
           DEBUGLOG("PartyManager::DeserializeNetworkDescriptor failed: 0x%08x\n", error);
           return;
       }

       // attempt to connect to the network
       PartyNetwork* network;
       error = PartyManager::GetSingleton().ConnectToNetwork(
           &networkDescriptor,
           nullptr,
           &network);
       if (PARTY_FAILED(error))
       {
           DEBUGLOG("PartyManager::ConnectToNetwork failed: 0x%08x\n", error);
           return;
       }

       // immediately queue an authentication on the network we've attempted to connect to.
       error = network->AuthenticateLocalUser(
           m_localUser,
           invitationId,
           nullptr);
       if (PARTY_FAILED(error))
       {
           DEBUGLOG("PartyNetwork::AuthenticateLocalUser failed: 0x%08x\n", error);
           return;
       }
   }
   ```

<Note>
  Nous avons présenté ici un flux permettant d'intégrer le matchmaking et MPSD à PlayFab Party. Les idées essentielles de ce flux peuvent être étendues à d'autres flux MPSD qui pourraient vous intéresser, mais la présentation de tous les flux possibles dépasse le cadre de cette documentation. Pour plus d'informations, consultez la [documentation MPSD complète](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/live/get-started/live-xbl-overview).
</Note>

<a id="platform-invites" />

## Invitations de plateforme

Voici un flux qui montre comment intégrer les invitations de plateforme XBOX à PlayFab Party :

1. *PlayerA* crée un document de session MPSD, écoute les modifications de la session et crée un réseau Party. Une fois la création du réseau Party terminée, *PlayerA* publie le descripteur de réseau et une invitation initiale (si nécessaire) dans le document de session MPSD.

   ```cpp theme={null}
   void
   OnSessionDocumentCreated()
   {
       // This is an asynchronous call. It will be completed when StartProcessingStateChanges generates a
       // PartyCreateNewNetworkCompletedStateChange struct
       PartyError error = PartyManager::GetSingleton().CreateNewNetwork(
           m_localPartyUser,
           &networkConfiguration,
           0,
           nullptr,
           nullptr,
           nullptr,
           nullptr,
           nullptr);
       if (FAILED(error))
       {
           DEBUGLOG("PartyManager::CreateNetwork failed! 0x%08x\n", error);
           return;
       }
   }

   void
   HandleCreateNewNetworkCompleted(
       const PartyCreateNewNetworkCompletedStateChange& createNewNetworkCompletedStateChange
       )
   {
       if (createNewNetworkCompletedStateChange.result == PartyStateChangeResult::Succeeded)
       {
           // The network was created successfully! Post the networks descriptor and invitation

           char serializedDescriptor[c_maxSerializedNetworkDescriptorStringLength + 1];
           PartyError error = PartyManager::SerializeNetworkDescriptor(
               &createNewNetworkCompletedStateChange.networkDescriptor,
               serializedDescriptor);
           if (PARTY_FAILED(error))
           {
               DEBUGLOG("PartyManager::SerializeNetworkDescriptor failed: 0x%08x\n", error);
               return;
           }

           UpdateSessionProperty(
               "PartyNetworkDescriptor", // arbitrary property name
               serializedDescriptor);
       }
       else
       {
           // The network was not created successfully.
           // Please refer to CreateNewNetwork reference documentation for retry guidance
       }
   }
   ```

2. Lorsque *PlayerA* souhaite inviter *PlayerB* sur le réseau Party, *PlayerA* envoie une invitation de plateforme à *PlayerB* via l'interface utilisateur du jeu ou de la console.

3. *PlayerB* reçoit l'invitation de plateforme, qui comprend un « handle d'invitation » que *PlayerB* peut utiliser pour trouver le document de session MPSD de *PlayerA*.

4. *PlayerB* rejoint le document de session et écoute les modifications.

5. *PlayerA* constate que *PlayerB* a rejoint le document de session. *PlayerA* crée une nouvelle invitation que *PlayerB* pourra utiliser et publie cette invitation dans le document de session

   ```cpp theme={null}
   void
   OnUserJoinedSessionDocument(
       PartyNetwork* network,
       uint64_t newSessionMemberXboxUserId
       )
   {
       std::string newMemberIdString = std::to_string(newSessionMemberXboxUserId);

       // Specify our own invitation id so we don't have to query for it after the invitation has been created.
       // Here we will specify the invite id with the format "InviterXboxUserID_InviteeXboxUserID" so that we can
       // ensure this invitation ID doesn't clash with the invitations other members might try and create for this user.
       std::string invitationId = std::to_string(m_localXboxUserId) + "_" + newMemberIdString;

       PartyInvitationConfiguration newInvite{};
       newInvite.identifier = invitationId.c_str();
       newInvite.revocability = PartyInvitationRevocability::Creator; // must be revocable by the creator only

       // Call title-defined xuid->entityid mapping helper
       PartyString newSessionMemberEntityId = GetEntityIdFromXboxUserId(newSessionMemberXboxUserId);
       newInvite.entityIdCount = 1;
       newInvite.entityIds = &newSessionMemberEntityId;

       // Create a new invitation which includes all of the users currently in the document
       PartyInvitation* newInvitation;
       PartyError error = network->CreateInvitation(
           m_localUser,
           &newInvite,
           nullptr,
           &newInvitation);
       if (PARTY_FAILED(error))
       {
           DEBUGLOG("PartyNetwork(0x%p)::CreateInvitation failed! (error=0x%x)", network, error);
           return;
       }

       // Post the invitation to the local user's member property store in the session document, key'd by the invitee's
       // xbox user id. This will let the invitee recognize when an invitation is intended for them.
       UpdateMemberProperty(
           newMemberIdString.c_str(),
           invitationId.c_str());
   }
   ```

6. *PlayerB* voit l'invitation publiée dans le document de session et l'utilise pour rejoindre le réseau Party.

   ```cpp theme={null}
   void
   OnRemoteMemberPropertyUpdated(
       PartyString memberPropertyKey,
       PartyString memberPropertyValue
       )
   {
       // The member property update signifies a new invitation, if the remote member updated a property that matches
       // our xbox user id.
       if (memberPropertyKey == std::to_string(m_localXboxUserId))
       {
           OnUserInvitationPostedToSessionDocument(memberPropertyValue);
       }

       // ...
   }

   void
   OnUserInvitationPostedToSessionDocument(
       PartyString invitationId
       )
   {
       // The network descriptor should have already been posted to the session document before the invitation.
       // Call title-defined function to pull it from the session document.
       PartyNetworkDescriptor networkDescriptor = QueryNetworkDescriptorFromSessionDocument();

       // attempt to connect to the network
       PartyNetwork* network;
       error = PartyManager::GetSingleton().ConnectToNetwork(
           &networkDescriptor,
           nullptr,
           &network);
       if (PARTY_FAILED(error))
       {
           DEBUGLOG("PartyManager::ConnectToNetwork failed: 0x%08x\n", error);
           return;
       }

       // immediately queue an authentication on the network we've attempted to connect to.
       error = network->AuthenticateLocalUser(
           m_localUser,
           invitationId,
           nullptr);
       if (PARTY_FAILED(error))
       {
           DEBUGLOG("PartyNetwork::AuthenticateLocalUser failed: 0x%08x\n", error);
           return;
       }
   }
   ```

<Info>
  Les invitations créées via [PartyNetwork::CreateInvitation](/fr/services/playfab/multiplayer/networking/reference/classes/PartyNetwork/methods/partynetwork_createinvitation) deviennent non valides si le PartyLocalUser qui les a créées quitte le réseau. Par conséquent, si un nouvel utilisateur s'ajoute à un document de session mais que l'utilisateur qui l'a invité quitte le réseau, il est recommandé que le nouvel utilisateur se retire du document de session et attende d'être réinvité par un autre utilisateur.
</Info>

## Jonction en cours de partie

La jonction de sessions de jeu en cours est très similaire au scénario des [invitations de plateforme](#platform-invites). La principale différence est qu'au lieu que *PlayerA* envoie un « handle d'invitation » à *PlayerB*, *PlayerB* obtient un « handle de jonction » lorsqu'il lance une jonction en cours de partie depuis l'interface utilisateur de la plateforme. À l'aide de ce « handle de jonction », *PlayerB* rejoint le document de session et écoute les modifications. *PlayerA* répond en créant une nouvelle invitation Party pour lui et en la publiant dans le document de session. *PlayerB* voit cette nouvelle invitation à côté du descripteur de réseau et l'utilise pour rejoindre le réseau Party.

<Info>
  Les invitations créées via [PartyNetwork::CreateInvitation](/fr/services/playfab/multiplayer/networking/reference/classes/PartyNetwork/methods/partynetwork_createinvitation) deviennent non valides si le PartyLocalUser qui les a créées quitte le réseau. Par conséquent, si un nouvel utilisateur reçoit une invitation Party par le flux de jonction en cours de partie, mais ne peut pas l'utiliser parce que l'utilisateur qui l'a créée est parti, il est recommandé que le nouvel utilisateur se retire du document de session et le rejoigne plus tard. Cela permettra à un autre membre de la session de relancer le flux et de générer une nouvelle invitation Party pour cet utilisateur.
</Info>

## Déconnexions et nettoyage

Si un joueur quitte un réseau Party ou en est déconnecté d'une autre manière, il doit également se retirer de toutes les sessions MPSD associées à ce réseau Party. Les déconnexions d'un réseau Party qui ne sont pas initiées par une opération [PartyNetwork::LeaveNetwork](/fr/services/playfab/multiplayer/networking/reference/classes/PartyNetwork/methods/partynetwork_leavenetwork) sont considérées comme fatales. Après une déconnexion fatale, un joueur peut essayer de se reconnecter et de se réauthentifier auprès du réseau, mais il doit également rejoindre de nouveau la session MPSD.

Si la connexion d'un joueur à une session MPSD est temporairement interrompue, il peut être déconnecté de cette session. Les joueurs peuvent tenter de rejoindre de nouveau la session, mais en cas d'échec, ils doivent se retirer volontairement du réseau Party en appelant [PartyNetwork::LeaveNetwork](/fr/services/playfab/multiplayer/networking/reference/classes/PartyNetwork/methods/partynetwork_leavenetwork).

<Note>
  Les mécanismes et heuristiques qui détectent les déconnexions des réseaux Party et des sessions MPSD sont différents. Même dans les scénarios où un joueur sera déconnecté à la fois du réseau Party et de la session MPSD, ces événements de déconnexion sont indépendants et il n'est pas garanti qu'ils se produisent à des moments proches. Les titres doivent gérer le scénario dans lequel un joueur n'est déconnecté que du réseau Party ou que de la session MPSD.
</Note>

Si le jeu s'arrête, le joueur est automatiquement déconnecté du réseau Party et du document MPSD, et aucun nettoyage supplémentaire n'est nécessaire.


## Related topics

- [Exigences XBOX](/fr/services/playfab/multiplayer/networking/xbox-requirements.md)
- [Utilisation de plusieurs réseaux PlayFab Party](/fr/services/playfab/multiplayer/networking/concepts-multiple-networks.md)
- [Utilisation des ports et exigences de pare-feu de PlayFab Party](/fr/services/playfab/multiplayer/networking/concepts-port-usage.md)
- [Démarrage rapide de Party](/fr/services/playfab/multiplayer/networking/quickstart.md)
- [Utiliser le GDK avec Unity](/fr/build/gdk-and-engines/unity/unity.md)
