Przesyłanie obrazów za pomocą interfejsu Play Games Services Publishing API

Interfejs Google Play Game Services Publishing API umożliwia przesyłanie obrazu do zasobu gry.

Opcje przesyłania

Interfejs Google Play Game Services Publishing API umożliwia przesyłanie określonych typów danych binarnych lub multimediów. Szczegółowe cechy danych, które możesz przesłać, są podane na stronie referencyjnej każdej metody obsługującej przesyłanie multimediów:

  • Maksymalny rozmiar przesyłanego pliku: maksymalna ilość danych, jaką możesz przechowywać za pomocą tej metody.

  • Akceptowane typy MIME multimediów: typy danych binarnych, które możesz przechowywać za pomocą tej metody.

Żądania przesyłania możesz wysyłać na jeden z tych sposobów. Określ metodę, której używasz, za pomocą parametru żądania uploadType.

  • Proste przesyłanie: uploadType=media. Do szybkiego przesyłania mniejszych plików, np. o rozmiarze 5 MB lub mniejszym.

  • Przesyłanie wieloczęściowe: uploadType=multipart. Do szybkiego przesyłania mniejszych plików i metadanych. Przesyła plik wraz z metadanymi, które go opisują, w ramach jednego żądania.

  • Przesyłanie z możliwością wznowienia: uploadType=resumable Zapewnia niezawodny transfer, co jest szczególnie ważne w przypadku większych plików. W tej metodzie używasz żądania inicjującego sesję, które opcjonalnie może zawierać metadane. Jest to dobra strategia w przypadku większości aplikacji, ponieważ działa też w przypadku mniejszych plików, ale wiąże się z jednym dodatkowym żądaniem HTTP na przesłanie.

Podczas przesyłania multimediów używasz specjalnego identyfikatora URI. Metody obsługujące przesyłanie plików multimedialnych mają 2 punkty końcowe URI:

  • Identyfikator URI /upload dla multimediów. Format punktu końcowego przesyłania to standardowy identyfikator URI zasobu z prefiksem „/upload”. Użyj tego URI podczas przesyłania samych danych multimedialnych.

    Przykład: POST /upload/games/v1configuration/images/resourceId/imageType/imageType

  • Standardowy identyfikator URI zasobu dla metadanych. Jeśli zasób zawiera pola danych, są one używane do przechowywania metadanych opisujących przesłany plik. Możesz użyć tego identyfikatora URI podczas tworzenia lub aktualizowania wartości metadanych.

    Przykład: POST /games/v1configuration/images/resourceId/imageType/imageType

Proste przesyłanie

Najprostszą metodą przesyłania pliku jest wysłanie prostego żądania przesłania. Ta opcja jest dobrym wyborem, jeśli spełniony jest jeden z tych warunków:

  • Plik jest wystarczająco mały, aby w przypadku awarii połączenia można było go ponownie przesłać w całości.

  • Nie ma metadanych do wysłania. Może to być przydatne, jeśli planujesz wysłać metadane tego zasobu w osobnym żądaniu lub jeśli metadane nie są obsługiwane ani dostępne. Aby użyć prostego przesyłania, wyślij żądanie POST lub PUT do URI /upload metody i dodaj parametr zapytania uploadType=media. Na przykład:

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

Nagłówki HTTP, które należy użyć podczas wysyłania prostego żądania przesyłania, to:

  • Content-Type. Ustaw na jeden z akceptowanych typów danych multimedialnych do przesyłania, określonych w dokumentacji interfejsu Publishing API.

  • Content-Length. Ustaw na liczbę przesyłanych bajtów. Nie jest wymagane, jeśli używasz kodowania przesyłania fragmentami.

Przykład: proste przesyłanie

Ten przykład pokazuje użycie prostego żądania przesyłania w interfejsie Play Games Services Publishing API.

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

Jeśli żądanie zakończy się powodzeniem, serwer zwróci kod stanu HTTP 200 OK wraz z metadanymi. Na przykład:

HTTP/1.1 200
Content-Type: application/json

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

Przesyłanie wieloczęściowe

Jeśli masz metadane, które chcesz wysłać wraz z danymi do przesłania, możesz wysłać pojedynczą prośbę multipart/related. To dobra opcja, jeśli przesyłane dane są wystarczająco małe, aby w przypadku awarii połączenia można było ponownie przesłać je w całości.

Aby użyć przesyłania wieloczęściowego, wyślij żądanie POST lub PUT do identyfikatora URI /upload metody i dodaj parametr zapytania uploadType=multipart. Na przykład:

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

Nagłówki HTTP najwyższego poziomu, które należy użyć podczas wysyłania żądania przesyłania wieloczęściowego, to:

-Content-Type. Ustaw wartość multipart/related i dołącz ciąg znaków granicznych, którego używasz do identyfikowania części żądania.

-Content-Length. Ustaw na łączną liczbę bajtów w treści żądania. Część żądania zawierająca multimedia musi być mniejsza niż maksymalny rozmiar pliku określony dla tej metody.

Treść żądania jest sformatowana jako typ treści multipart/related RFC2387 i zawiera dokładnie 2 części. Poszczególne części są identyfikowane za pomocą ciągu ograniczającego, a po ostatnim ciągu ograniczającym znajdują się dwa łączniki.

Każda część żądania wieloczęściowego wymaga dodatkowego nagłówka Content-Type:

  • Część metadanych: musi być pierwsza, a wartość Content-Type musi być zgodna z jednym z akceptowanych formatów metadanych.

  • Część multimedialna: musi być druga, a typ treści musi być zgodny z jednym z akceptowanych typów MIME multimediów w metodzie.

Listę akceptowanych typów MIME multimediów i limitów rozmiaru przesyłanych plików dla każdej metody znajdziesz w dokumentacji interfejsu Publishing API.

Przykład: przesyłanie wieloczęściowe

Poniższy przykład pokazuje żądanie przesyłania wieloczęściowego w interfejsie Google Play Game Services Publishing API.

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

Jeśli żądanie zakończy się powodzeniem, serwer zwróci kod stanu HTTP 200 OK wraz z metadanymi:

HTTP/1.1 200
Content-Type: application/json

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

Przesyłanie z możliwością wznowienia

Aby przesyłać pliki danych w bardziej niezawodny sposób, możesz użyć protokołu przesyłania możliwego do wznowienia. Ten protokół umożliwia wznowienie przesyłania po przerwaniu przepływu danych z powodu awarii komunikacji. Jest to szczególnie przydatne, gdy przesyłasz duże pliki i istnieje duże prawdopodobieństwo przerwy w działaniu sieci lub innego błędu transmisji, np. podczas przesyłania z aplikacji mobilnej. Może też zmniejszyć wykorzystanie przepustowości w przypadku awarii sieci, ponieważ nie musisz ponownie przesyłać dużych plików od początku.

Czynności związane z używaniem przesyłania możliwego do wznowienia:

  1. Rozpocznij sesję z możliwością wznowienia. Wyślij początkowe żądanie do identyfikatora URI przesyłania, które zawiera metadane (jeśli występują).

  2. Zapisz identyfikator URI sesji z możliwością wznowienia. Zapisz identyfikator URI sesji zwrócony w odpowiedzi na początkowe żądanie. Będzie on potrzebny w przypadku pozostałych żądań w tej sesji. Prześlij plik.

  3. Wyślij plik multimedialny do identyfikatora URI sesji z możliwością wznowienia.

Aplikacje, które korzystają z przesyłania możliwego do wznowienia, muszą też zawierać kod umożliwiający wznowienie przerwanego przesyłania. Jeśli przesyłanie zostanie przerwane, sprawdź, ile danych zostało przesłanych, a następnie wznow przesyłanie od tego momentu.

Rozpoczynanie sesji z możliwością wznowienia

Aby rozpocząć przesyłanie z możliwością wznowienia, wyślij żądanie POST lub PUT do identyfikatora URI /upload metody i dodaj parametr zapytania uploadType=resumable. Na przykład:

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

W przypadku tego żądania inicjującego treść jest pusta lub zawiera tylko metadane. Rzeczywistą zawartość pliku, który chcesz przesłać, prześlesz w kolejnych żądaniach.

Użyj tych nagłówków HTTP w przypadku żądania początkowego:

  • X-Upload-Content-Type. Ustaw na typ MIME przesyłanych danych, które mają być przesyłane w kolejnych żądaniach.

  • X-Upload-Content-Length. Ustaw na liczbę bajtów danych przesyłanych w kolejnych żądaniach. Jeśli długość jest nieznana w momencie wysłania tej prośby, możesz pominąć ten nagłówek.

  • Jeśli podajesz metadane: Content-Type. Ustaw zgodnie z typem danych metadanych.

  • Content-Length. Ustaw na liczbę bajtów podaną w treści tego pierwszego żądania. Nie jest wymagane, jeśli używasz kodowania przesyłania fragmentami.

Listę akceptowanych typów MIME multimediów i limity rozmiaru przesyłanych plików dla każdej metody znajdziesz w dokumentacji interfejsu Publishing API.

Przykład: żądanie rozpoczęcia sesji z możliwością wznowienia

Poniższy przykład pokazuje, jak zainicjować sesję z możliwością wznowienia w interfejsie Google Play Game Services Publishing API.

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
}

W następnej sekcji opisujemy, jak postępować w przypadku odpowiedzi.

Zapisz identyfikator URI sesji z możliwością wznowienia

Jeśli żądanie rozpoczęcia sesji zakończy się powodzeniem, serwer interfejsu API odpowie kodem stanu HTTP 200 OK. Dodatkowo zawiera nagłówek Location, który określa identyfikator URI sesji z możliwością wznowienia. Nagłówek Location, widoczny w przykładzie poniżej, zawiera część parametru zapytania upload_id, która podaje unikalny identyfikator przesyłania do użycia w tej sesji.

Przykład: odpowiedź na rozpoczęcie sesji z możliwością wznowienia

Oto odpowiedź na żądanie z kroku 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

Wartość nagłówka Location, jak w przykładzie odpowiedzi powyżej, to URI sesji, którego będziesz używać jako punktu końcowego HTTP do przesyłania plików lub sprawdzania stanu przesyłania.

Skopiuj i zapisz identyfikator URI sesji, aby móc go używać w kolejnych żądaniach.

Przesyłanie pliku

Aby przesłać plik, wyślij żądanie PUT do identyfikatora URI przesyłania uzyskanego w poprzednim kroku. Format żądania przesyłania:

PUT session_uri

Nagłówki HTTP, które mają być używane podczas wysyłania żądań przesyłania plików z możliwością wznowienia, obejmują:Content-Length Ustaw tę wartość na liczbę bajtów przesyłanych w tym żądaniu, która jest zwykle rozmiarem przesyłanego pliku.

Przykład: żądanie przesyłania pliku z możliwością wznowienia

Oto przykładowe żądanie z możliwością wznowienia, które umożliwia przesłanie całego pliku PNG o rozmiarze 2 000 000 bajtów.

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

Jeśli żądanie się powiedzie, serwer odpowie kodem HTTP 201 Created oraz metadanymi powiązanymi z tym zasobem. Jeśli początkowe żądanie sesji z możliwością wznowienia było żądaniem PUT, aby zaktualizować istniejący zasób, odpowiedź o powodzeniu będzie miała postać 200 OK wraz z metadanymi powiązanymi z tym zasobem.

Jeśli żądanie przesłania zostanie przerwane lub otrzymasz odpowiedź HTTP 503 Service Unavailable albo inną odpowiedź 5xx z serwera, postępuj zgodnie z procedurą opisaną w artykule wznawianie przerwanego przesyłania.

Przesyłanie pliku w częściach

Dzięki przesyłaniu z możliwością wznowienia możesz podzielić plik na części i wysłać serię żądań, aby przesłać każdą część po kolei. Nie jest to zalecane podejście, ponieważ dodatkowe żądania wiążą się z kosztami związanymi z wydajnością i zwykle nie są potrzebne. Może jednak być konieczne użycie dzielenia na części, aby zmniejszyć ilość danych przesyłanych w ramach jednego żądania. Jest to przydatne, gdy poszczególne żądania mają stały limit czasu, jak w przypadku niektórych klas żądań Google App Engine. Umożliwia też m.in. wyświetlanie informacji o postępach przesyłania w starszych przeglądarkach, które domyślnie nie obsługują tej funkcji.

Jeśli przesyłasz dane w częściach, wymagany jest też nagłówek Content-Range, a także nagłówek Content-Length, który jest wymagany w przypadku przesyłania całych plików:

  • Content-Length. Ustaw na rozmiar fragmentu lub mniej, jak w przypadku ostatniego żądania.

  • Content-Range Ustaw, aby wyświetlać, które bajty w przesyłanym pliku są przesyłane. Na przykład Content-Range: bytes 0-524287/2000000 oznacza, że w pliku o rozmiarze 2 000 000 bajtów podajesz pierwsze 524 288 bajtów (256 x 1024 x 2).

Wznawianie przerwanego przesyłania

Jeśli żądanie przesłania zostanie zakończone przed otrzymaniem odpowiedzi lub jeśli otrzymasz z serwera odpowiedź HTTP 503 Service Unavailable, musisz wznowić przerwane przesyłanie. Aby wznowić przerwane przesyłanie, wykonaj te czynności:

  1. Stan żądania Sprawdź bieżący stan przesyłania, wysyłając puste żądanie PUT do identyfikatora URI przesyłania. W tym żądaniu nagłówki HTTP powinny zawierać nagłówek Content-Range wskazujący, że bieżąca pozycja w pliku jest nieznana. Jeśli np. łączna długość pliku wynosi 2 000 000, ustaw wartość Content-Range na */2000000. Jeśli nie znasz pełnego rozmiaru pliku, ustaw zakres Content-Range na */*.

  2. Pobierz liczbę przesłanych bajtów Przetwarzanie odpowiedzi na zapytanie o stan. Serwer używa w odpowiedzi nagłówka Range, aby określić, które bajty zostały dotychczas odebrane. Na przykład nagłówek Range0-299999 oznacza, że otrzymano pierwsze 300 000 bajtów pliku.

  3. Prześlij pozostałe dane. Na koniec, gdy już wiesz, gdzie wznowić żądanie, wyślij pozostałe dane lub bieżący fragment. Pamiętaj, że w obu przypadkach pozostałe dane musisz traktować jako oddzielną część, więc po wznowieniu przesyłania musisz wysłać nagłówek Content-Range.

Przykład: wznawianie przerwanych przesyłań

  1. Poproś o stan przesyłania. W tym żądaniu użyto nagłówka Content-Range,aby wskazać,że bieżąca pozycja w pliku o rozmiarze 2 000 000 bajtów jest nieznana.

    PUT {session_uri} HTTP/1.1
    Content-Length: 0
    Content-Range: bytes */2000000
    
  2. Wyodrębnij z odpowiedzi liczbę bajtów przesłanych do tej pory. Odpowiedź serwera zawiera nagłówek Range, który wskazuje, że serwer otrzymał do tej pory pierwsze 43 bajty pliku. Użyj górnej wartości nagłówka Range, aby określić, od którego miejsca rozpocząć wznowione przesyłanie.

    HTTP/1.1 308 Resume Incomplete
    Content-Length: 0
    Range: 0-42
    
  3. Wznów przesyłanie od miejsca, w którym zostało przerwane. Poniższe żądanie wznawia przesyłanie, wysyłając pozostałe bajty pliku, począwszy od bajtu 43.

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

Obsługa błędów

Podczas przesyłania plików multimedialnych warto znać sprawdzone metody związane z obsługą błędów.

  • Wznawianie lub ponawianie przesyłania, które nie powiodło się z powodu przerw w połączeniu lub błędów z serii 5xx, w tym:

    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • Jeśli podczas wznawiania lub ponawiania przesyłania żądań zostanie zwrócony jakikolwiek 5xx błąd serwera, użyj strategii wykładniczego wycofywania. Te błędy mogą wystąpić, jeśli serwer jest przeciążony. Wycofywanie wykładnicze może pomóc w rozwiązaniu tego typu problemów w okresach dużej liczby żądań lub dużego ruchu w sieci.

  • Inne rodzaje żądań nie powinny być obsługiwane przez wycofywanie wykładnicze, ale nadal możesz ponawiać niektóre z nich. Podczas ponawiania tych żądań ogranicz liczbę prób. Na przykład kod może ograniczać liczbę ponownych prób do 10 lub mniej przed zgłoszeniem błędu.

  • Obsługuj błędy 404 Not Found410 Gone podczas przesyłania z możliwością wznowienia, rozpoczynając przesyłanie od początku.

Wzrastający czas do ponowienia

Wycofywanie się z prób ponowienia połączenia to standardowa strategia obsługi błędów w aplikacjach sieciowych, w której klient okresowo ponawia nieudane żądanie przez coraz dłuższy czas. Jeśli duża liczba żądań lub duże natężenie ruchu w sieci powodują, że serwer zwraca błędy, dobrym rozwiązaniem może być wycofywanie wykładnicze. Nie jest to natomiast odpowiednia strategia w przypadku błędów niezwiązanych z ruchem w sieci ani czasem odpowiedzi, takich jak nieprawidłowe dane uwierzytelniające lub błędy „nie znaleziono pliku”.

Prawidłowo użyty algorytm Exponential backoff zwiększa wydajność wykorzystania przepustowości, zmniejsza liczbę żądań potrzebnych do uzyskania odpowiedzi i maksymalizuje przepustowość żądań w środowiskach współbieżnych.

Proces wdrażania prostego wzrastającego czasu do ponowienia wygląda tak:

  1. Wyślij żądanie do interfejsu API.
  2. Otrzymasz odpowiedź HTTP 503, która oznacza, że należy ponowić żądanie.
  3. Odczekaj 1 sekundę + losową liczbę milisekund i spróbuj ponownie.
  4. Otrzymasz odpowiedź HTTP 503, która oznacza, że należy ponowić żądanie.
  5. Odczekaj 2 sekundy + losowa_liczba_milisekund i spróbuj ponownie.
  6. Otrzymasz odpowiedź HTTP 503, która oznacza, że należy ponowić żądanie.
  7. Odczekaj 4 sekundy + random_number_milliseconds i spróbuj ponownie.
  8. Otrzymasz kod HTTP 503 response, który oznacza, że należy ponowić żądanie.
  9. Odczekaj 8 sekund + losowa_liczba_milisekund i spróbuj ponownie.
  10. Otrzymasz kod HTTP 503 response, który oznacza, że należy ponowić żądanie.
  11. Odczekaj 16 sekund + random_number_milliseconds i spróbuj jeszcze raz.
  12. Zatrzymaj. Zgłoś lub zarejestruj błąd.

Na liście powyżej random_number_milliseconds to losowa liczba milisekund mniejsza lub równa 1000. Jest to konieczne, ponieważ wprowadzenie niewielkiego losowego opóźnienia pomaga bardziej równomiernie rozłożyć obciążenie i uniknąć możliwości przeciążenia serwera. Wartość random_number_milliseconds musi być ponownie zdefiniowana po każdym oczekiwaniu.

Algorytm ma się zakończyć, gdy n = 5. Ten limit zapobiega nieskończonemu ponawianiu prób przez klientów i powoduje, że łączne opóźnienie przed uznaniem żądania za „błąd nie do odzyskania” wynosi około 32 sekundy. Większa maksymalna liczba ponownych prób jest w porządku, zwłaszcza jeśli trwa długie przesyłanie. Pamiętaj tylko, aby ograniczyć opóźnienie ponownej próby do rozsądnej wartości, np. poniżej minuty.

Przewodniki po bibliotekach klienta API