Caricare immagini con l'API Play Games Services Publishing

L'API Pubblicazione nei servizi per i giochi di Play ti consente di caricare un'immagine per una risorsa di gioco.

Opzioni di caricamento

L'API Pubblicazione nei servizi per i giochi di Play ti consente di caricare determinati tipi di dati binari o contenuti multimediali. Le caratteristiche specifiche dei dati che puoi caricare sono specificate nella pagina di riferimento per qualsiasi metodo che supporti i caricamenti di contenuti multimediali:

  • Dimensione massima del file di caricamento: la quantità massima di dati che puoi archiviare con questo metodo.

  • Tipi MIME di contenuti multimediali accettati: i tipi di dati binari che puoi archiviare utilizzando questo metodo.

Puoi effettuare richieste di caricamento in uno dei seguenti modi. Specifica il metodo che stai utilizzando con il parametro di richiesta uploadType.

  • Caricamento semplice: uploadType=media. Per il trasferimento rapido di file più piccoli, ad esempio 5 MB o meno.

  • Caricamento in più parti: uploadType=multipart. Per il trasferimento rapido di file e metadati più piccoli, trasferisce il file insieme ai metadati che lo descrivono, il tutto in un'unica richiesta.

  • Caricamento ripristinabile: uploadType=resumable. Per un trasferimento affidabile, particolarmente importante con i file di grandi dimensioni. Con questo metodo, utilizzi una richiesta di avvio della sessione, che può includere facoltativamente i metadati. Si tratta di una buona strategia da utilizzare per la maggior parte delle applicazioni, poiché funziona anche per i file più piccoli al costo di una richiesta HTTP aggiuntiva per caricamento.

Quando carichi contenuti multimediali, utilizzi un URI speciale. Infatti, i metodi che supportano i caricamenti di contenuti multimediali hanno due endpoint URI:

  • L'URI /upload, per i contenuti multimediali. Il formato dell'endpoint di caricamento è l'URI della risorsa standard con il prefisso "/upload". Utilizza questo URI durante il trasferimento dei dati multimediali.

    Esempio: POST /upload/games/v1configuration/images/resourceId/imageType/imageType

  • L'URI risorsa standard per i metadati. Se la risorsa contiene campi di dati, questi vengono utilizzati per archiviare i metadati che descrivono il file caricato. Puoi utilizzare questo URI quando crei o aggiorni i valori dei metadati.

    Esempio: POST /games/v1configuration/images/resourceId/imageType/imageType

Caricamento semplice

Il metodo più semplice per caricare un file è inviare una semplice richiesta di caricamento. Questa opzione è una buona scelta quando una delle seguenti condizioni è vera:

  • Il file è abbastanza piccolo da poter essere caricato nuovamente per intero in caso di interruzione della connessione.

  • Non ci sono metadati da inviare. Ciò potrebbe essere vero se prevedi di inviare metadati per questa risorsa in una richiesta separata o se non sono supportati o disponibili metadati. Per utilizzare il caricamento semplice, invia una richiesta POST o PUT all'URI /upload del metodo e aggiungi il parametro di query uploadType=media. Ad esempio:

POST https://www.googleapis.com/upload/games/v1configuration/images/resourceId/imageType/imageType?uploadType=media

Le intestazioni HTTP da utilizzare quando si effettua una semplice richiesta di caricamento includono:

  • Content-Type. Imposta uno dei tipi di dati multimediali di caricamento accettati dal metodo, specificati nel riferimento dell'API Publishing.

  • Content-Length. Imposta il numero di byte che stai caricando. Non richiesto se utilizzi la codifica di trasferimento chunked.

Esempio: caricamento semplice

L'esempio seguente mostra l'utilizzo di una semplice richiesta di caricamento per l'API Play Games Services Publishing.

POST /upload/games/v1configuration/images/resourceId/imageType/imageType?uploadType=media HTTP/1.1
Host: www.googleapis.com
Content-Type: image/png
Content-Length: number_of_bytes_in_file
Authorization: Bearer your_auth_token

PNG data

Se la richiesta riesce, il server restituisce il codice di stato HTTP 200 OK insieme a eventuali metadati. Ad esempio:

HTTP/1.1 200
Content-Type: application/json

{
  "kind": "gamesConfiguration#imageConfiguration",
  "url": string,
  "resourceId": string,
  "imageType": string
}

Caricamento multiparte

Se hai metadati da inviare insieme ai dati da caricare, puoi effettuare una singola richiesta multipart/related. Questa è una buona scelta se i dati che invii sono abbastanza piccoli da essere caricati di nuovo per intero in caso di interruzione della connessione.

Per utilizzare il caricamento in più parti, invia una richiesta POST o PUT all'URI /upload del metodo e aggiungi il parametro di query uploadType=multipart. Ad esempio:

POST https://www.googleapis.com/upload/games/v1configuration/images/resourceId/imageType/imageType?uploadType=multipart

Le intestazioni HTTP di primo livello da utilizzare quando si effettua una richiesta di caricamento in più parti includono:

-Content-Type. Imposta su multipart/related e includi la stringa di delimitazione che utilizzi per identificare le parti della richiesta.

-Content-Length. Imposta il numero totale di byte nel corpo della richiesta. La parte multimediale della richiesta deve essere inferiore alle dimensioni massime del file specificate per questo metodo.

Il corpo della richiesta è formattato come tipo di contenuto multipart/related RFC2387 e contiene esattamente due parti. Le parti sono identificate da una stringa di delimitazione e la stringa di delimitazione finale è seguita da due trattini.

Ogni parte della richiesta con più parti richiede un'intestazione Content-Type aggiuntiva:

  • Parte dei metadati: deve essere la prima e Content-Type deve corrispondere a uno dei formati di metadati accettati.

  • Parte multimediale: deve essere la seconda e il tipo di contenuto deve corrispondere a uno dei tipi MIME multimediali accettati dal metodo.

Consulta il riferimento dell'API Publishing per l'elenco dei tipi MIME di media accettati e i limiti di dimensioni per i file caricati di ogni metodo.

Esempio: caricamento multiparte

L'esempio seguente mostra una richiesta di caricamento in più parti per l'API Pubblicazione nei servizi per i giochi di Play.

POST /upload/games/v1configuration/images/resourceId/imageType/imageType?uploadType=multipart HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Type: multipart/related; boundary=foo_bar_baz
Content-Length: number_of_bytes_in_entire_request_body

--foo_bar_baz
Content-Type: application/json; charset=UTF-8

{
  "kind": "gamesConfiguration#imageConfiguration",
  "url": string,
  "resourceId": string,
  "imageType": string
}

--foo_bar_baz
Content-Type: image/png

PNG data
--foo_bar_baz--

Se la richiesta riesce, il server restituisce il codice di stato HTTP 200 OK insieme a eventuali metadati:

HTTP/1.1 200
Content-Type: application/json

{
  "kind": "gamesConfiguration#imageConfiguration",
  "url": string,
  "resourceId": string,
  "imageType": string
}

Caricamento ripristinabile

Per caricare i file di dati in modo più affidabile, puoi utilizzare il protocollo di caricamento ripristinabile. Questo protocollo consente di riprendere un'operazione di caricamento dopo che un errore di comunicazione ha interrotto il flusso di dati. È particolarmente utile se stai trasferendo file di grandi dimensioni e la probabilità di un'interruzione di rete o di un altro errore di trasmissione è elevata, ad esempio quando carichi da un'app client mobile. Può anche ridurre l'utilizzo della larghezza di banda in caso di errori di rete, perché non devi riavviare i caricamenti di file di grandi dimensioni dall'inizio.

I passaggi per utilizzare il caricamento ripristinabile includono:

  1. Avvia una sessione ripristinabile. Effettua una richiesta iniziale all'URI di caricamento che include i metadati, se presenti.

  2. Salva l'URI della sessione ripristinabile. Salva l'URI della sessione restituito nella risposta della richiesta iniziale. Lo utilizzerai per le richieste rimanenti in questa sessione. Carica il file.

  3. Invia il file multimediale all'URI della sessione ripristinabile.

Inoltre, le app che utilizzano il caricamento ripristinabile devono avere codice per riprendere un caricamento interrotto. Se un caricamento viene interrotto, scopri quanti dati sono stati ricevuti correttamente e riprendi il caricamento da quel punto.

Avviare una sessione ripristinabile

Per avviare un caricamento ripristinabile, invia una richiesta POST o PUT all'URI /upload del metodo e aggiungi il parametro di query uploadType=resumable. Ad esempio:

POST https://www.googleapis.com/upload/games/v1configuration/images/resourceId/imageType/imageType?uploadType=resumable

Per questa richiesta iniziale, il corpo è vuoto o contiene solo i metadati; trasferirai i contenuti effettivi del file che vuoi caricare nelle richieste successive.

Utilizza le seguenti intestazioni HTTP con la richiesta iniziale:

  • X-Upload-Content-Type. Imposta il tipo MIME multimediale dei dati di caricamento da trasferire nelle richieste successive.

  • X-Upload-Content-Length. Imposta il numero di byte dei dati di caricamento da trasferire nelle richieste successive. Se la lunghezza non è nota al momento di questa richiesta, puoi omettere questa intestazione.

  • Se fornisci i metadati: Content-Type. Imposta in base al tipo di dati dei metadati.

  • Content-Length. Imposta il numero di byte forniti nel corpo di questa richiesta iniziale. Non è obbligatorio se utilizzi la codifica di trasferimento chunked.

Consulta il riferimento dell'API Publishing per l'elenco dei tipi MIME dei media accettati e i limiti di dimensione per i file caricati per ogni metodo.

Esempio: richiesta di avvio di sessione ripristinabile

Il seguente esempio mostra come avviare una sessione ripristinabile per l'API Play Games Services Publishing.

POST /upload/games/v1configuration/images/resourceId/imageType/imageType?uploadType=resumable HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Length: 38
Content-Type: application/json; charset=UTF-8
X-Upload-Content-Type: image/png
X-Upload-Content-Length: 2000000

{
  "kind": "gamesConfiguration#imageConfiguration",
  "url": string,
  "resourceId": string,
  "imageType": string
}

La sezione successiva descrive come gestire la risposta.

Salva l'URI della sessione ripristinabile

Se la richiesta di avvio della sessione va a buon fine, il server API risponde con un codice di stato HTTP 200 OK. Inoltre, fornisce un'intestazione Location che specifica l'URI della sessione ripristinabile. L'intestazione Location, mostrata nell'esempio di seguito, include una parte del parametro di query upload_id che fornisce l'ID caricamento univoco da utilizzare per questa sessione.

Esempio: risposta di avvio della sessione ripristinabile

Ecco la risposta alla richiesta del passaggio 1:

HTTP/1.1 200 OK
Location: https://www.googleapis.com/upload/games/v1configuration/images/resourceId/imageType/imageType?uploadType=resumable&upload_id=xa298sd_sdlkj2
Content-Length: 0

Il valore dell'intestazione Location, come mostrato nella risposta di esempio riportata sopra, è l'URI della sessione che utilizzerai come endpoint HTTP per eseguire il caricamento effettivo del file o per interrogare lo stato del caricamento.

Copia e salva l'URI della sessione per poterlo utilizzare per le richieste successive.

Caricamento del file

Per caricare il file, invia una richiesta PUT all'URI di caricamento ottenuto nel passaggio precedente. Il formato della richiesta di caricamento è:

PUT session_uri

Le intestazioni HTTP da utilizzare quando si effettuano le richieste di caricamento dei file ripristinabile includono Content-Length. Imposta questo valore sul numero di byte che stai caricando in questa richiesta, che in genere corrisponde alle dimensioni del file di caricamento.

Esempio: richiesta di caricamento di file ripristinabile

Di seguito è riportata una richiesta ripristinabile per caricare l'intero file PNG di 2.000.000 di byte per l'esempio attuale.

PUT https://www.googleapis.com/upload/games/v1configuration/images/resourceId/imageType/imageType?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1
Content-Length: 2000000
Content-Type: image/png

bytes 0-1999999

Se la richiesta ha esito positivo, il server risponde con un messaggio HTTP 201 Created, insieme a tutti i metadati associati a questa risorsa. Se la richiesta iniziale della sessione ripristinabile era un PUT per aggiornare una risorsa esistente, la risposta di esito positivo sarebbe 200 OK, insieme a tutti i metadati associati a questa risorsa.

Se la richiesta di caricamento viene interrotta o se ricevi una risposta HTTP 503 Service Unavailable o qualsiasi altra risposta 5xx dal server, segui la procedura descritta in Riprendere un caricamento interrotto.

Carica il file in blocchi

Con i caricamenti ripristinabili, puoi dividere un file in blocchi e inviare una serie di richieste per caricare ogni blocco in sequenza. Questo non è l'approccio preferito in quanto sono associati costi di rendimento alle richieste aggiuntive e in genere non è necessario. Tuttavia, potresti dover utilizzare la suddivisione in blocchi per ridurre la quantità di dati trasferiti in una singola richiesta. Ciò è utile quando esiste un limite di tempo fisso per le singole richieste, come nel caso di determinate classi di richieste Google App Engine. Consente inoltre di eseguire operazioni come fornire indicazioni sull'avanzamento del caricamento per i browser legacy che non supportano l'avanzamento del caricamento per impostazione predefinita.

Se carichi i dati in blocchi, è necessaria anche l'intestazione Content-Range, oltre all'intestazione Content-Length richiesta per i caricamenti di file completi:

  • Content-Length. Imposta la dimensione del chunk o un valore inferiore, come potrebbe essere il caso dell'ultima richiesta.

  • Content-Range. Imposta la visualizzazione dei byte nel file che stai caricando. Ad esempio, Content-Range: bytes 0-524287/2000000 mostra che stai fornendo i primi 524.288 byte (256 x 1024 x 2) in un file di 2.000.000 di byte.

Riprendere un caricamento interrotto

Se una richiesta di caricamento viene terminata prima di ricevere una risposta o se ricevi una risposta HTTP 503 Service Unavailable dal server, devi riprendere il caricamento interrotto. Per riprendere un caricamento interrotto:

  1. Stato della richiesta. Esegui una query sullo stato attuale del caricamento inviando una richiesta PUT vuota all'URI di caricamento. Per questa richiesta, le intestazioni HTTP devono includere un'intestazione Content-Range che indica che la posizione corrente nel file è sconosciuta. Ad esempio, imposta Content-Range su */2000000 se la lunghezza totale del file è 2.000.000. Se non conosci le dimensioni complete del file, imposta Content-Range su */*.

  2. Recupera il numero di byte caricati. Elabora la risposta della query di stato. Il server utilizza l'intestazione Range nella risposta per specificare i byte che ha ricevuto finora. Ad esempio, un'intestazione Range di 0-299999 indica che sono stati ricevuti i primi 300.000 byte del file.

  3. Carica i dati rimanenti. Infine, ora che sai dove riprendere la richiesta, invia i dati rimanenti o il blocco corrente. Tieni presente che devi trattare i dati rimanenti come un blocco separato in entrambi i casi, quindi devi inviare l'intestazione Content-Range quando riprendi il caricamento.

Esempio: riprendere un caricamento interrotto

  1. Richiedi lo stato di caricamento. La seguente richiesta utilizza l'intestazione Content-Range per indicare che la posizione corrente nel file di 2.000.000 di byte è sconosciuta.

    PUT {session_uri} HTTP/1.1
    Content-Length: 0
    Content-Range: bytes */2000000
    
  2. Estrai dalla risposta il numero di byte caricati finora. La risposta del server utilizza l'intestazione Range per indicare che finora ha ricevuto i primi 43 byte del file. Utilizza il valore superiore dell'intestazione Range per determinare da dove iniziare il caricamento ripreso.

    HTTP/1.1 308 Resume Incomplete
    Content-Length: 0
    Range: 0-42
    
  3. Riprendi il caricamento dal punto in cui è stato interrotto. La seguente richiesta riprende il caricamento inviando i byte rimanenti del file, a partire dal byte 43.

    PUT {session_uri} HTTP/1.1
    Content-Length: 1999957
    Content-Range: bytes 43-1999999/2000000
    
    bytes 43-1999999
    

Gestione degli errori

Quando carichi contenuti multimediali, è utile conoscere alcune best practice relative alla gestione degli errori.

  • Riprendi o riprova i caricamenti non riusciti a causa di interruzioni della connessione o di errori 5xx, tra cui:

    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • Utilizza una strategia di backoff esponenziale se viene restituito un errore del server 5xx durante la ripresa o il nuovo tentativo di caricamento delle richieste. Questi errori possono verificarsi se un server è sovraccarico. Il backoff esponenziale può contribuire ad alleviare questi tipi di problemi durante i periodi di volume elevato di richieste o di traffico di rete intenso.

  • Altri tipi di richieste non devono essere gestiti tramite il backoff esponenziale, ma puoi comunque riprovare a eseguirne alcune. Quando riprovi a inviare queste richieste, limita il numero di tentativi. Ad esempio, il codice potrebbe limitare a dieci o meno i tentativi prima di segnalare un errore.

  • Gestisci gli errori 404 Not Found e 410 Gone durante i caricamenti ripristinabili riavviando l'intero caricamento dall'inizio.

Backoff esponenziale

Il backoff esponenziale è una strategia standard di gestione degli errori per le applicazioni di rete in cui il client riprova periodicamente una richiesta non riuscita per un periodo di tempo sempre più lungo. Se un volume elevato di richieste o un traffico di rete intenso causano la restituzione di errori da parte del server, il backoff esponenziale può essere una buona strategia per la gestione di questi errori. Al contrario, non è una strategia pertinente per la gestione di errori non correlati al volume di rete o ai tempi di risposta, come credenziali di autorizzazione non valide o errori di file non trovato.

Se utilizzato correttamente, il backoff esponenziale aumenta l'efficienza dell'utilizzo della larghezza di banda, riduce il numero di richieste necessarie per ottenere una risposta riuscita e massimizza il throughput delle richieste in ambienti simultanei.

Il flusso per l'implementazione del backoff esponenziale semplice è il seguente:

  1. Effettua una richiesta all'API.
  2. Ricevi una risposta HTTP 503, che indica che devi riprovare a inviare la richiesta.
  3. Attendi un secondo + numero_casuale_di_millisecondi e riprova a inviare la richiesta.
  4. Ricevi una risposta HTTP 503, che indica che devi riprovare a inviare la richiesta.
  5. Attendi 2 secondi + numero_casuale_di_millisecondi e riprova a inviare la richiesta.
  6. Ricevi una risposta HTTP 503, che indica che devi riprovare a inviare la richiesta.
  7. Attendi 4 secondi + numero_casuale_di_millisecondi e riprova a inviare la richiesta.
  8. Ricevi un HTTP 503 response, che indica che devi riprovare a inviare la richiesta.
  9. Attendi 8 secondi + numero_casuale_di_millisecondi e riprova a inviare la richiesta.
  10. Ricevi un HTTP 503 response, che indica che devi riprovare a inviare la richiesta.
  11. Attendi 16 secondi + numero_casuale_di_millisecondi e riprova a inviare la richiesta.
  12. Interrompi. Segnala o registra un errore.

Nell'elenco precedente, numero_casuale_di_millisecondi è un numero casuale di millisecondi minore o uguale a 1000. Ciò è necessario, poiché l'introduzione di un piccolo ritardo casuale contribuisce a distribuire il carico in modo più uniforme ed evita la possibilità di sovraccaricare il server. Il valore di random_number_milliseconds deve essere ridefinito dopo ogni attesa.

L'algoritmo è impostato per terminare quando n è 5. Questo limite impedisce ai client di riprovare all'infinito e comporta un ritardo totale di circa 32 secondi prima che una richiesta venga considerata "un errore non recuperabile". Un numero massimo di tentativi più elevato va bene, soprattutto se è in corso un caricamento lungo; assicurati solo di limitare il ritardo tra i tentativi a un valore ragionevole, ad esempio inferiore a un minuto.

Guide alle librerie client delle API