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

# Depurar servidores de jogo em contêiner com o LocalMultiplayerAgent

> Depure localmente um servidor de jogo multijogador do PlayFab empacotando-o como um contêiner Linux ou Windows e executando-o no LocalMultiplayerAgent no modo de contêiner.

# Como executar um servidor de jogo usando o LocalMultiplayerAgent no modo de contêiner

Este tutorial descreve como:

* Criar um build de contêiner \[Linux/Windows] usando o exemplo Wrapper
* Configurar o MultiplayerSettings.json
* Configurar o Docker
* Executar o LocalMultiplayerAgent
* Testar a conexão do seu jogo

## Criar um build de contêiner \[Linux/Windows]

Se você não estiver familiarizado com contêineres, consulte [Introdução a contêineres e ao Docker](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/container-docker-introduction/).

Vamos aprender a empacotar um exemplo existente como um contêiner Windows ou Linux. Você precisará definir configurações diferentes para plataformas diferentes (contêiner baseado em Windows/Linux). Aqui usaremos o exemplo Wrapper e veremos os detalhes.

### Build de contêiner Linux

Você pode executar os executáveis wrapper e fakegame em um build Linux, usando contêineres Linux. Nesse caso, você precisa criar um build Linux.
Para saber como criar o build Linux do Wrapper, consulte [como criar uma imagem de contêiner Linux](/pt-BR/services/playfab/multiplayer/servers/wrapper-sample#create-and-upload-linux-container-image-for-linux-servers-only)

### Build de contêiner Windows

O LMA criará um build de contêiner Windows para você. Você só precisa definir as configurações corretamente (veja mais adiante como definir as configurações para o contêiner Windows)

## Configurar o MultiplayerSettings.json

Navegue até a pasta em que você extraiu o conjunto de ferramentas do LMA e abra o arquivo MultiplayerSettings.json. Esse arquivo é um arquivo simulado de configuração de build que simula o build no MPS.

Você também pode preencher um json usando o [Gerador de MultiplayerSettings.json do LMA](https://github.com/PlayFab/MpsAgent/tree/main/LocalMultiplayerAgent/SettingsJsonGenerator). O Gerador é uma página da Web simples que cria um json com base nas suas opções. Você pode encontrar o Gerador em LocalMultiplayerAgent/SettingsJsonGenerator.

Veja a seguir um exemplo de MultiplayerSettings.Json para executar o exemplo Wrapper como `Linux Container`.

```json theme={null}
{
    "RunContainer": true, // Set RunContainer to true if you are running LMA in Container mode.
    "OutputFolder": "C:\\output\\LMAContainer", // Path where config files and logs will be generated from LMA at each run
    "NumHeartBeatsForActivateResponse": 10,
    "NumHeartBeatsForTerminateResponse": 60,
    "TitleId": "", // default value
    "BuildId": "00000000-0000-0000-0000-000000000000", // default value
    "Region": "59F84", // default value
    "AgentListeningPort": 56001, // default value
    "ContainerStartParameters": {
        /// replace ImageDetails fields to your own images saved on ACR.
        "ImageDetails": {
            "Registry": "mydockerregistry.io",
            "ImageName": "wrapper",
            "ImageTag": "0.1",
            "Username": "",
            "Password": ""
        }
    },
    "PortMappingsList": [
        [
            {
                "NodePort": 56100,
                "GamePort": {
                    "Name": "game_port", 
                    // The same value of GamePort Name should be also defined in the Wrapper so Wrapper can get a port information while it's running.
                    "Number": 80,
                    "Protocol": "TCP"
                }
            }
        ]
    ],
}
```

Para `Windows Container`, você não precisa criar seu contêiner. O LMA empacotará seu servidor de jogo como um contêiner Windows. Você só precisa especificar a imagem base do contêiner Windows no campo `ImageDetails` e definir `LocalFilePath` como o local em que o ativo do seu jogo está na sua estação de trabalho.

```json theme={null}
"AssetDetails": [
    {
      "MountPath": "C:\\Assets",  
      // Mount Path should be "C:\\Assets" for Windows Container. 
      "LocalFilePath": "D:\\gameassets.zip" 
      // where your game server is located as an archive format.
    }
  ]

 "ContainerStartParameters": {
    "StartGameCommand": "C:\\Assets\\wrapper.exe -g C:\\Assets\\fakegame.exe arg1 arg2", 
    // Your game assets will be extracted under C:\\Assets (default mount path for Windows Container) and LMA will run your game server with StartGameCommand argument. 
     // Make sure the StartGameCommand provided above is an example of the Wrapper sample. 
    "ImageDetails": {
      "Registry": "mcr.microsoft.com",
      "ImageName": "playfab/multiplayer",
      "ImageTag": "wsc-10.0.17763.973.1",
      "Username": "", 
      "Password": ""
      // username and password are not required to use MCR image.
    }
    // LMA will package an existing game sample (path defined in LocalFilePath) as a Windows container.
 }

```

Certifique-se de atualizar corretamente os seguintes campos no MultiplayerSettings.json para executar o LMA no modo de contêiner.

* `LocalFilePath`: caminho local completo (na sua estação de trabalho) para o arquivo zip de ativos do servidor de jogo criado anteriormente, por exemplo: D:\gameassets.zip (observe que as barras invertidas precisam ser escapadas para a formatação JSON). Esse campo é obrigatório para o contêiner Windows, pois o LMA precisa localizar o ativo do seu jogo e, em seguida, empacotá-lo em um contêiner.

* `PortMappingsList`: são as portas disponíveis para o seu jogo durante a execução.

  * `NodePort` é a porta aberta na sua estação de trabalho que será mapeada para a GamePort.
  * `GamePort.Number` é a porta à qual seu servidor de jogo precisa se associar ao ser executado em um contêiner. Por exemplo, aqui definimos o número da porta como 80, que o fakegame.exe escutará.
  * Defina `GamePort.Name` com o mesmo valor definido no seu servidor de jogo. Você pode verificar o valor na configuração do GSDK em runtime, com a chave GamePort.Name.
  * `GamePort.Protocol`: especifique o tipo de protocolo: TCP ou UDP

  Atualize a seção GamePort para corresponder ao protocolo e à porta em que seu servidor de jogo escuta os clientes. Você pode adicionar várias portas.

* `ForcePullFromAcrOnLinuxContainersOnWindows`: defina como true quando quiser efetuar pull da imagem de contêiner Linux do Docker Registry e evitar o pull do registro local. Na maioria dos casos, convém definir como false.

* `ContainerStartParameters.ImageDetails`: a imagem do seu servidor de jogo pode ser publicada em um registro de contêiner ou criada localmente. Se quiser efetuar pull da imagem de contêiner Linux do Docker Registry (por exemplo, Azure Registry), você precisará definir valores para o nome de usuário e a senha e definir `ForcePullFromAcrOnLinuxContainersOnWindows` como true. Para o contêiner Windows, o nome de usuário e a senha não são necessários.

* `OutputFolder`: caminho para uma unidade ou pasta em que as saídas e os arquivos de configuração são gerados. Verifique se há espaço suficiente disponível, pois o servidor de jogo será extraído nesse caminho. Se não for especificado, a pasta do agente será usada.

* `AgentListeningPort`: é a porta para o LMA se comunicar com o servidor de jogo. Qualquer porta aberta funcionará; 56001 é o valor padrão. Se houver outro processo associado à porta 56001, você deverá alterar esse valor ou encerrar o outro processo na porta 56001.

* `ResourceLimits` (opcional): se especificado, o docker limita o uso de CPU/memória. Aviso: se o seu servidor ultrapassar a memória permitida, ele será encerrado. ResourceLimits só pode ser especificado no modo de contêiner.

* `SessionCookie` (opcional): qualquer cookie de sessão que é passado ao seu servidor de jogo como parte da chamada à API RequestMultiplayerServer. No cenário real no MPS, depois que a conexão é estabelecida, o servidor notifica o cliente para carregar os recursos correspondentes a partir do SessionCookie.

## Configuração do Docker

Execute scripts do PowerShell para configurar as redes do docker chamadas "PlayFab" e adicionar regras de firewall para a comunicação com o LocalMultiplayerAgent.

* Para o contêiner Linux, execute `SetupLinuxContainersOnWindows.ps1`.\
  Para o contêiner Windows, execute `Setup.ps1`. Ele efetuará pull da imagem do docker do PlayFab de Microsoft/PlayFab-Multiplayer.\
  Observe que, na primeira vez que o script é executado, o download da imagem de contêiner pode levar alguns minutos.
  > Para executar essa configuração com êxito, talvez seja necessário configurar o firewall de qualquer programa antivírus de terceiros que você tenha instalado.

Para saber como direcionar o daemon do docker correto entre contêineres Windows e Linux, consulte [Como alternar o Docker para usar contêineres Windows/Linux](https://docs.docker.com/desktop/windows/#switch-between-windows-and-linux-containers)

## Executar o LocalMultiplayerAgent

* Em uma janela do PowerShell:\
  Navegue até o diretório do LMA que contém o LocalMultiplayerAgent.exe.

* Execute `LocalMultiplayerAgent.exe` para o contêiner Windows.\
  Execute `LocalMultiplayerAgent.exe -lcow` para o contêiner Linux.\
  (lcow significa Linux Containers On Windows)

  Neste ponto, o LMA configura o ouvinte http e executa um contêiner.
  Você pode executar o comando `docker ps` para ver os contêineres em execução no seu computador.

O LMA aguardará as pulsações do GSDK integrado ao seu servidor de jogo.
Se o GSDK estiver integrado corretamente, o LMA imprimirá as saídas na seguinte ordem:

1. `CurrentGameState - Initializing`\
   (Isso pode não aparecer se o seu servidor de jogo chamar GSDK::ReadyForPlayers diretamente e não chamar GSDK::Start)
2. `CurrentGameState - StandingBy`
3. `CurrentGameState - Active`
4. `CurrentGameState - Terminating`

Para saber mais sobre os estados de um servidor de jogo, consulte [O que é o ciclo de vida do servidor de jogo do PlayFab Multiplayer Server](/pt-BR/services/playfab/multiplayer/servers/multiplayer-game-server-lifecycle).

Se os retornos de chamada de desligamento estiverem configurados corretamente, o servidor de jogo será encerrado logo depois que o estado for definido como Terminating.
É importante verificar se o servidor de jogo é encerrado, para evitar desligamentos abruptos na plataforma PlayFab.

O LMA também deve ser encerrado junto com o jogo.

## Testar a conexão com o seu jogo

Depois que o LMA imprimir **CurrentGameState - Active**, você poderá se conectar ao seu servidor de jogo usando o endereço IP 127.0.0.1 e a porta NodePort na qual o servidor de jogo está escutando.

Se você estiver usando o exemplo Wrapper, poderá testar uma solicitação GET inserindo o endereço [http://127.0.0.1:56100/Hello](http://127.0.0.1:56100/Hello) no navegador.
Para obter mais detalhes, confira o exemplo Wrapper.

Você também pode atualizar os valores de **NumHeartBeatsForActivateResponse** e **NumHeartBeatsForTerminateResponse** no MultiplayerSettings.json para ajustar a duração dos estados standing-by/active.

### Solução de problemas

* No modo de contêiner, se o servidor de jogo for encerrado imediatamente com um erro semelhante a "Container ... exited with exit code 1", mas funcionar bem no modo de processo, verifique se você incluiu todas as [DLLs do sistema](/pt-BR/services/playfab/multiplayer/servers/determining-required-dlls) necessárias no seu pacote de ativos.
* Todos os logs ficam em `OutputFolder`, especificado no arquivo *MultiplayerSettings.json*. O **LocalMultiplayerAgent** cria uma nova pasta sempre que é iniciado, com o carimbo de data/hora como nome da pasta. Todos os logs do servidor de jogo emitidos por meio do GSDK ficam na pasta GameLogs.\
  Se o servidor de jogo estiver sendo executado em um contêiner, pode haver um nível adicional na hierarquia de diretórios a ser percorrido.
* O GSDK grava logs de depuração na pasta GameLogs em `OutputFolder`.
  Esses logs ficam na pasta GameLogs junto com os logs gerados pelo servidor de jogo.
* Verifique se os firewalls (do Windows e de outros antivírus) estão configurados para permitir o tráfego pelas portas.
* Se você receber um erro semelhante a: `Docker API responded with status code=InternalServerError, response={"message":"failed to create endpoint <container_name> on network playfab: hnsCall failed in Win32: The specified port already exists". It is likely there is already a container running on the specified port.` Isso pode acontecer se o **LocalMultiplayerAgent** for encerrado prematuramente. Use o comando `docker ps` para encontrar o contêiner em execução e, em seguida, exclua-o usando `docker kill <container_name>`.
* Se você receber um erro que contenha `Failed to find network 'playfab'`, tente executar *Setup.ps1* novamente

### Limitações conhecidas

1. Os contêineres podem não ser encerrados ao final da depuração. Se isso ocorrer, execute os seguintes comandos do PowerShell como Administrador. Esses comandos param e removem todos os contêineres, incluindo os que não foram iniciados pelo **LocalMultiplayerAgent**.

```powershell theme={null}
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)  
```


## Related topics

- [Depurar servidores de jogo baseados em processo usando o LocalMultiplayerAgent](/pt-BR/services/playfab/multiplayer/servers/LocalMultiplayerAgent/run-process-based-gameserver.md)
- [Conectar-se diretamente para depurar servidores de jogo](/pt-BR/services/playfab/multiplayer/servers/directly-debugging-game-servers.md)
- [Depurando servidores de jogo localmente e integração com o PlayFab](/pt-BR/services/playfab/multiplayer/servers/locally-debugging-game-servers-and-integration-with-playfab.md)
- [Visão geral do LocalMultiplayerAgent](/pt-BR/services/playfab/multiplayer/servers/LocalMultiplayerAgent/local-multiplayer-agent-overview.md)
- [Teste e depuração do projeto GSDK](/pt-BR/services/playfab/multiplayer/servers/server-sdks/unreal-gsdk/third-person-mp-example-project-local-deployment-and-debugging.md)
