

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Amazon GameLift ServersFari ping UDP
<a name="reference-udp-ping-beacons"></a>

I beacon ping UDP forniscono un modo per misurare la latenza di rete tra i dispositivi dei giocatori e le posizioni di hosting. Amazon GameLift Servers Con i ping beacon, puoi raccogliere dati di latenza accurati per prendere decisioni informate sul posizionamento dei server di gioco e migliorare il matchmaking dei giocatori in base ai requisiti di latenza.

## Come funzionano i ping beacon UDP
<a name="reference-how-beacons-work"></a>

Amazon GameLift Serversfornisce endpoint UDP fissi (ping beacon) in ogni posizione di hosting in cui è possibile distribuire server di gioco. Poiché la maggior parte dei server di gioco comunica tramite UDP, la misurazione della latenza con i beacon ping UDP fornisce risultati più accurati rispetto all'utilizzo dei ping ICMP. I dispositivi di rete spesso gestiscono i pacchetti ICMP in modo diverso dai pacchetti UDP, il che può portare a misurazioni della latenza che non riflettono le prestazioni reali dei giocatori.

Con i ping beacon UDP, il tuo client di gioco può inviare messaggi UDP a questi endpoint e ricevere risposte asincrone, ottenendo misurazioni della latenza che rappresentano meglio le condizioni effettive del traffico di gioco tra il dispositivo di un giocatore e le potenziali località di hosting. Gli endpoint sono permanenti e rimangono disponibili fintanto che supporta l'hosting di giochi in quella posizione. Amazon GameLift Servers

## Casi d'uso comuni dei beacon ping UDP
<a name="reference-beacons-common-use-cases"></a>

Puoi utilizzare i beacon ping UDP in diversi modi per ottimizzare l'esperienza di rete del gioco.

**Scelta delle location di hosting ottimali**  
Raccogli i dati sulla latenza in diverse aree geografiche per identificare le migliori posizioni primarie e di backup per ospitare i server di gioco per la tua base di giocatori.

**Posizionamento delle sessioni di gioco in base alla latenza dei giocatori**  
Includi i dati sulla latenza dei giocatori quando richiedi nuove sessioni di gioco per aiutarti a scegliere le località che offrono l'esperienza di latenza più bassa.

**Ottimizzazione del matchmaking in base alla latenza**  
Fornisci dati sulla latenza dei giocatori quando richiedi il matchmaking per aiutare ad abbinare giocatori con profili di latenza simili e a collocare le sessioni di gioco in posizioni ottimali per i giocatori abbinati.

**Nota**  
Quando crei richieste di matchmaking, non dovresti fornire informazioni sulla latenza a località in cui non disponi di flotte. In tal caso, Amazon GameLift Servers potresti provare a collocare la sessione di gioco in luoghi in cui la flotta non è disponibile, con conseguenti errori nelle richieste di matchmaking.

## Ottenere endpoint beacon
<a name="reference-beacons-getting-endpoints"></a>

Per recuperare le informazioni sul dominio e sulla porta del ping beacon per le Amazon GameLift Servers posizioni, utilizza l'operazione API. [ListLocations](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_ListLocations.html) Il set di posizioni restituito da questa API dipende dalla regione specificata al Regione AWS momento della chiamata (o dalla regione predefinita se non ne specifichi una).

Quando chiami da:
+ **Una regione di origine di una flotta che supporta più sedi**: l'API restituisce informazioni per *tutte le* sedi di hosting
+ **Una regione di origine di un parco veicoli che supporta un'unica ubicazione**: l'API restituisce le informazioni relative a quella località

Tieni presente che se chiami questa API utilizzando una posizione che può essere solo una posizione remota in un parco di sedi multiple, l'API restituirà un errore perché quel tipo di posizione non dispone di un endpoint di servizio.

Consulta la tabella delle località supportate in [AWS Località supportate](gamelift-regions.md#gamelift-regions-hosting-home) per identificare le aree geografiche che supportano flotte con una o più sedi.

**Esempio**

```
aws gamelift list-locations --region ap-northeast-2
```

Questo Regione AWS supporta flotte con più sedi, pertanto verranno restituite più sedi. Ecco un esempio di uno dei valori restituiti:

```
[...]
{
    "LocationName": "ap-northeast-1",
    "PingBeacon": {
        "UDPEndpoint": {
            "Domain": "gamelift-ping.ap-northeast-1.api.aws",
            "Port": 7770
        }
    }
}
```

**Importante**  
Memorizza nella cache le informazioni del beacon ping anziché chiamare `ListLocations` prima di ogni misurazione della latenza. Le informazioni sul dominio e sulla porta sono statiche e l'API non è progettata per richieste ad alto volume.

## Implementazione della misurazione della latenza
<a name="reference-beacons-measuring-latency"></a>

Segui queste best practice quando implementi le misurazioni della latenza utilizzando i beacon ping UDP:

1. Memorizza le informazioni sui ping beacon utilizzando uno di questi approcci:
   + Codifica gli endpoint nel tuo client di gioco.
   + Memorizza le informazioni nel backend del gioco.
   + Implementa un meccanismo di aggiornamento periodico (giornaliero/settimanale) per aggiornare le informazioni.

1. Invia messaggi ping UDP:
   + Inserisci quello che vuoi nel corpo del messaggio, purché non sia vuoto, e mantieni i messaggi al di sotto della dimensione massima di 300 byte.
   + Rispetta i seguenti limiti di velocità per ogni località:
     + 3 transazioni al secondo (TPS) per combinazione univoca di indirizzo IP e porta del mittente
     + 1000 TPS per indirizzo IP univoco del mittente

1. Calcola la latenza:
   + Invia più ping a ciascuna posizione per calcolare una latenza media.
   + Valuta la possibilità di inviare ping simultanei a più sedi per risultati più rapidi.
   + Se necessario, utilizzate la logica di ripetizione per inviare nuovi pacchetti per qualsiasi pacchetto che non sia stato restituito entro breve tempo (in genere 1-3 secondi), poiché UDP non offre una consegna garantita al 100%.
   + Calcola la differenza di tempo tra l'invio di un messaggio e la ricezione della risposta.
   + Se una gran parte dei ping UDP verso una posizione non ottiene costantemente una risposta, calcola la latenza utilizzando i ping ICMP ai nostri endpoint di [Amazon GameLift Serversservizio](https://docs.aws.amazon.com/general/latest/gr/gamelift.html#gamelift_region) standard come fallback.

**Suggerimento**  
Ti consigliamo di includere la porta 7770 ovunque documenti l'elenco delle porte che i giocatori devono avere aperte sulla rete locale. Questo è un altro motivo per cui dovresti disporre di un sistema di riserva per misurare la latenza (usando ICMP, ad esempio) nel caso in cui questa porta sia bloccata.

## Esempi di codice
<a name="reference-beacons-code-examples"></a>

Ecco alcuni semplici esempi che mostrano come inviare ping UDP e calcolare la latenza.

------
#### [ C\+\+ ]

```
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <chrono>

int main() {
    // Replace with Amazon GameLift Servers UDP ping beacon domain for your desired location
    const char* domain = "gamelift-ping.ap-south-1.api.aws";  
    const int port = 7770;              
    const char* message = "Ping";        // Your message
    const int num_pings = 3;             // Number of pings to send

    // Create socket
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {
        std::cerr << "Error creating socket" << std::endl;
        return 1;
    }

    // Resolve domain name to IP address
    struct hostent* host = gethostbyname(domain);
    if (host == nullptr) {
        std::cerr << "Error resolving hostname" << std::endl;
        close(sock);
        return 1;
    }

    // Set up the server address structure
    struct sockaddr_in server_addr;
    std::memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    std::memcpy(&server_addr.sin_addr, host->h_addr, host->h_length);

    // Set socket timeout
    struct timeval tv;
    tv.tv_sec = 1;  // 1 second timeout
    tv.tv_usec = 0;
    if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
        std::cerr << "Error setting socket timeout" << std::endl;
        close(sock);
        return 1;
    }

    double total_latency = 0;
    int successful_pings = 0;

    for (int i = 0; i < num_pings; ++i) {
        auto start = std::chrono::high_resolution_clock::now();

        // Send the message
        ssize_t bytes_sent = sendto(sock, message, std::strlen(message), 0,
                                    (struct sockaddr*)&server_addr, sizeof(server_addr));

        if (bytes_sent < 0) {
            std::cerr << "Error sending message" << std::endl;
            continue;
        }

        // Receive response
        char buffer[1024];
        socklen_t server_addr_len = sizeof(server_addr);
        ssize_t bytes_received = recvfrom(sock, buffer, sizeof(buffer), 0,
                                          (struct sockaddr*)&server_addr, &server_addr_len);

        auto end = std::chrono::high_resolution_clock::now();

        if (bytes_received < 0) {
            std::cerr << "Error receiving response or timeout" << std::endl;
        } else {
            std::chrono::duration<double, std::milli> latency = end - start;
            total_latency += latency.count();
            successful_pings++;

            std::cout << "Received response, latency: " << latency.count() << " ms" << std::endl;
        }

        // Wait a bit before next ping
        usleep(1000000);  // 1s
    }

    // Close the socket
    close(sock);

    if (successful_pings > 0) {
        double avg_latency = total_latency / successful_pings;
        std::cout << "Average latency: " << avg_latency << " ms" << std::endl;
    } else {
        std::cout << "No successful pings" << std::endl;
    }

    return 0;
}
```

------
#### [ C\# ]

```
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;

class UdpLatencyTest
{
    static async Task Main()
    {
        // Replace with Amazon GameLift Servers UDP ping beacon domain for your desired location
        string domain = "gamelift-ping.ap-south-1.api.aws";  
        int port = 7770;                
        string message = "Ping";         // Your message
        int numPings = 3;                // Number of pings to send
        int timeoutMs = 1000;            // Timeout in milliseconds

        await MeasureLatency(domain, port, message, numPings, timeoutMs);
    }

    static async Task MeasureLatency(string domain, int port, string message, int numPings, int timeoutMs)
    {
        using (var udpClient = new UdpClient())
        {
            try
            {
                // Resolve domain name to IP address
                IPAddress[] addresses = await Dns.GetHostAddressesAsync(domain);
                if (addresses.Length == 0)
                {
                    Console.WriteLine("Could not resolve domain name.");
                    return;
                }

                IPEndPoint endPoint = new IPEndPoint(addresses[0], port);
                byte[] messageBytes = Encoding.UTF8.GetBytes(message);

                // Set receive timeout
                udpClient.Client.ReceiveTimeout = timeoutMs;

                double totalLatency = 0;
                int successfulPings = 0;
                var stopwatch = new Stopwatch();

                for (int i = 0; i < numPings; i++)
                {
                    try
                    {
                        stopwatch.Restart();

                        // Send message
                        await udpClient.SendAsync(messageBytes, messageBytes.Length, endPoint);

                        // Wait for response
                        UdpReceiveResult result = await ReceiveWithTimeoutAsync(udpClient, timeoutMs);
                        
                        stopwatch.Stop();
                        double latency = stopwatch.Elapsed.TotalMilliseconds;
                        
                        totalLatency += latency;
                        successfulPings++;

                        string response = Encoding.UTF8.GetString(result.Buffer);
                        Console.WriteLine($"Ping {i + 1}: {latency:F2}ms - Response: {response}");
                    }
                    catch (SocketException ex)
                    {
                        Console.WriteLine($"Ping {i + 1}: Failed - {ex.Message}");
                    }
                    catch (TimeoutException)
                    {
                        Console.WriteLine($"Ping {i + 1}: Timeout");
                    }

                    // Wait before next ping
                    await Task.Delay(1000); // 1s between pings
                }

                if (successfulPings > 0)
                {
                    double averageLatency = totalLatency / successfulPings;
                    Console.WriteLine($"\nSummary:");
                    Console.WriteLine($"Successful pings: {successfulPings}/{numPings}");
                    Console.WriteLine($"Average latency: {averageLatency:F2}ms");
                }
                else
                {
                    Console.WriteLine("\nNo successful pings");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
        }
    }

    static async Task<UdpReceiveResult> ReceiveWithTimeoutAsync(UdpClient client, int timeoutMs)
    {
        using var cts = new System.Threading.CancellationTokenSource(timeoutMs);
        try
        {
            return await client.ReceiveAsync().WaitAsync(cts.Token);
        }
        catch (OperationCanceledException)
        {
            throw new TimeoutException("Receive operation timed out");
        }
    }
}
```

------
#### [ Python ]

```
import socket
import time
import statistics
from datetime import datetime

def udp_ping(host, port, timeout=2):
    """
    Send a UDP ping and return the round trip time in milliseconds.
    Returns None if timeout occurs.
    """
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.settimeout(timeout)
    message = b'ping'

    try:
        # Resolve hostname first
        try:
            socket.gethostbyname(host)
        except socket.gaierror as e:
            print(f"Could not resolve hostname: {e}")
            return None

        start_time = time.time()
        sock.sendto(message, (host, port))

        # Wait for response
        data, server = sock.recvfrom(1024)
        end_time = time.time()

        # Calculate round trip time in milliseconds
        rtt = (end_time - start_time) * 1000
        return rtt

    except socket.timeout:
        print(f"Request timed out")
        return None
    except Exception as e:
        print(f"Error: {type(e).__name__}: {e}")
        return None
    finally:
        sock.close()

def main():
    # Replace with Amazon GameLift Servers UDP ping beacon domain for your desired location
    host = "gamelift-ping.ap-south-1.api.aws"
    port = 7770
    num_pings = 3
    latencies = []

    print(f"\nPinging {host}:{port} {num_pings} times...")
    print(f"Start time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")

    for i in range(num_pings):
        print(f"Ping {i+1}:")
        rtt = udp_ping(host, port)

        if rtt is not None:
            print(f"Response from {host}: time={rtt:.2f}ms")
            latencies.append(rtt)

        # Wait 1 second between pings
        if i < num_pings - 1:
            time.sleep(1)
        print()

    # Calculate and display statistics
    print("-" * 50)
    print(f"Ping statistics for {host}:")
    print(f"    Packets: Sent = {num_pings}, Received = {len(latencies)}, "
          f"Lost = {num_pings - len(latencies)} "
          f"({((num_pings - len(latencies)) / num_pings * 100):.1f}% loss)")

    if latencies:
        print("\nRound-trip latency statistics:")
        print(f"    Minimum = {min(latencies):.2f}ms")
        print(f"    Maximum = {max(latencies):.2f}ms")
        print(f"    Average = {statistics.mean(latencies):.2f}ms")

    print(f"\nEnd time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")

if __name__ == "__main__":
    main()
```

------