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

Interfejs Play Games Services Publishing API umożliwia przesłanie obrazu zasobu gry.

Opcje przesyłania

Interfejs Play Games Services Publishing API umożliwia przesyłanie określonych typów danych binarnych lub multimediów. Cechy charakterystyczne danych, które można przesyłać, można określić na stronie referencyjnej każdej metody obsługującej przesyłanie multimediów:

  • Maksymalny rozmiar przesyłanego pliku: maksymalna ilość danych, które można przechowywać przy użyciu tej metody.

  • Akceptowane typy MIME multimediów: typy danych binarnych, które można przechowywać przy użyciu tej metody.

Prośby o przesłanie możesz przesyłać na każdy z tych sposobów. Określ metodę, której używasz z parametrem żądania sendType.

  • Proste przesyłanie: uploadType=media. Do szybkiego przesyłania mniejszych plików, np. nieprzekraczających 5 MB.

  • Przesyłanie wieloczęściowe: uploadType=multipart. Do szybkiego przenoszenia mniejszych plików i metadanych służy do przesłania pliku razem z metadanymi, które go opisują, w ramach jednego żądania.

  • Wznawianie przesyłania: uploadType=resumable. Zapewnia to niezawodne przenoszenie, szczególnie ważne przy dużych plikach. Używając tej metody, używasz żądania inicjującego sesję, która opcjonalnie może zawierać metadane. Jest to dobra strategia w przypadku większości aplikacji, ponieważ sprawdza się również w przypadku mniejszych plików i kosztuje jedno dodatkowe żądanie HTTP na każde przesłanie.

Do przesyłania multimediów używasz specjalnego identyfikatora URI. Metody, które obsługują przesyłanie multimediów, mają 2 punkty końcowe URI:

  • Identyfikator URI obiektu /upload dla multimediów. Format punktu końcowego przesyłania to standardowy identyfikator URI zasobu z prefiksem „/upload”. Służy on do przenoszenia danych multimedialnych.

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

  • Standardowy identyfikator URI zasobu dla metadanych. Jeśli zasób zawiera jakiekolwiek pola danych, służą one 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 przesłanie najprostszego żądania. Ta opcja jest dobrym wyborem, gdy jest spełniony jeden z tych warunków:

  • Plik jest wystarczająco mały, by przesłać go ponownie w całości w razie problemów z połączeniem.

  • Brak metadanych do wysłania. Może się tak zdarzyć, jeśli planujesz wysyłać metadane tego zasobu w osobnym żądaniu lub jeśli żadne metadane nie są obsługiwane bądź dostępne. Aby skorzystać z prostego przesyłania, wyślij żądanie POST lub PUT do identyfikatora URI /upload metody i dodaj parametr zapytania queryType=media. Na przykład:

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

Nagłówki HTTP, których należy użyć w prostym żądaniu przesłania, obejmują:

  • Content-Type. Ustaw jeden z akceptowanych typów przesyłanych danych o multimediach określonych w dokumentacji interfejsu Publishing API.

  • Content-Length. Ustaw liczbę bajtów, które chcesz przesłać. Niewymagane, jeśli używasz fragmentów kodowania transferu.

Przykład: proste przesyłanie

Przykład poniżej pokazuje wykorzystanie prostego żądania przesyłania dla interfejsu 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 zostanie zrealizowane, serwer zwróci kod stanu HTTP 200 OK wraz ze wszystkimi 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ć pojedyncze żądanie multipart/related. To dobry wybór, jeśli wysyłane dane są wystarczająco małe, by przesłać je ponownie w całości w razie niepowodzenia połączenia.

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 używane przy tworzeniu wieloczęściowego żądania przesyłania to m.in.:

-Content-Type. Ustaw wartość wieloczęściową/powiązaną i dołącz ciąg granicy używany do identyfikacji części żądania.

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

Treść żądania jest sformatowana jako wieloczęściowa/powiązany typ treści RFC2387 i zawiera dokładnie 2 części. Części te są wskazywane przez ciąg graniczny, po którym na końcu występują 2 łączniki.

Każda część wieloczęściowego żądania musi mieć dodatkowy nagłówek Content-Type:

  • Część metadanych: musi być umieszczona jako pierwsza, a element Content-Type musi być zgodny z jednym z akceptowanych formatów metadanych.

  • Część multimediów: musi być na drugiej pozycji, a typ treści musi być zgodny z jednym z akceptowanych typów MIME multimediów dla danej metody.

Listę akceptowanych typów MIME multimediów i limitów rozmiarów przesyłanych plików znajdziesz w dokumentacji interfejsu Publishing API.

Przykład: przesyłanie wieloczęściowe

Przykład poniżej pokazuje wieloczęściowe żądanie przesyłania za pomocą interfejsu Play Games 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 zostanie zrealizowane, serwer zwróci kod stanu HTTP 200 OK wraz ze wszystkimi 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 zwiększyć niezawodność przesyłania plików danych, możesz użyć protokołu przesyłania wznawiania. Protokół ten umożliwia wznowienie operacji przesyłania, gdy przepływ danych zostanie przerwany w wyniku błędu komunikacji. Jest to szczególnie przydatne w przypadku przesyłania dużych plików, w przypadku których prawdopodobieństwo przerw w działaniu sieci lub innej awarii transmisji jest wysokie, np. podczas przesyłania z aplikacji mobilnej klienckiej. W przypadku awarii sieci może też zmniejszyć wykorzystanie przepustowości, ponieważ od początku nie trzeba ponownie przesyłać dużych plików.

Aby włączyć przesyłanie z możliwością wznowienia:

  1. Rozpocznij sesję, którą można wznowić. Wyślij wstępne żądanie do identyfikatora URI przesyłania, które zawiera metadane (jeśli istnieją).

  2. Zapisz identyfikator URI sesji możliwej do wznowienia. Zapisz identyfikator URI sesji zwrócony w odpowiedzi na pierwsze żądanie. Będzie on potrzebny w pozostałych żądaniach w tej sesji. Prześlij plik.

  3. Wyślij plik multimedialny do identyfikatora URI sesji możliwej do wznowienia.

Poza tym aplikacje, które używają przesyłania z możliwością wznowienia, muszą mieć kod umożliwiający wznowienie przerwanego przesyłania. Jeśli przesyłanie zostanie przerwane, sprawdź, ile danych zostało odebranych, a następnie wznów przesyłanie, zaczynając od tego momentu.

Rozpoczynanie sesji możliwej do wznowienia

Aby zainicjować wznowienie przesyłania, 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

Treść tego żądania jest pusta lub zawiera tylko metadane. W kolejnych żądaniach przesyłasz rzeczywistą zawartość pliku, który chcesz przesłać.

W początkowym żądaniu użyj tych nagłówków HTTP:

  • X-Upload-Content-Type. Ustaw typ MIME multimediów, aby przesyłać dane, które mają być przesyłane w kolejnych żądaniach.

  • X-Upload-Content-Length. Ustaw liczbę bajtów danych, które mają być przesyłane w kolejnych żądaniach. Jeśli w momencie wysyłania żądania długość jest nieznana, możesz pominąć ten nagłówek.

  • W przypadku dostarczania metadanych: Content-Type. Ustawiany zgodnie z typem danych metadanych.

  • Content-Length. Ustaw liczbę bajtów podanych w treści tego początkowego żądania. Nie jest wymagane, jeśli używasz fragmentów kodowania transferu.

Listę akceptowanych typów MIME multimediów i limitów rozmiarów przesyłanych plików znajdziesz w dokumentacji interfejsu Publishing API.

Przykład: żądanie zainicjowania sesji możliwej do wznowienia

Z przykładu poniżej dowiesz się, jak zainicjować sesję wznawiania dla interfejsu API publikowania usług gier Play.

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 opisano, jak postępować z odpowiedzią.

Zapisz identyfikator URI sesji możliwej do wznowienia

Jeśli żądanie inicjowania sesji zostanie zrealizowane, serwer API odpowiada z kodem stanu HTTP 200 OK. Dodatkowo zawiera nagłówek Location, który określa identyfikator URI sesji możliwej do wznowienia. Nagłówek Location, widoczny w poniższym przykładzie, zawiera fragment parametru zapytania upload_id, który zapewnia unikalny identyfikator przesyłania używany w tej sesji.

Przykład: odpowiedź na zainicjowanie 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ładowej odpowiedzi powyżej, to identyfikator URI sesji, którego użyjesz jako punktu końcowego HTTP do rzeczywistego przesyłania pliku lub wysyłania zapytań dotyczących 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 na identyfikator URI przesyłania uzyskany w poprzednim kroku. Żądanie przesyłania ma taki format:

PUT session_uri

Nagłówki HTTP używane przy wysyłaniu żądań przesyłania plików z możliwością wznowienia obejmują element Content-Length. Ustaw ją na liczbę bajtów przesyłanych w tym żądaniu, która zazwyczaj odpowiada rozmiarowi przesyłanego pliku.

Przykład: prośba o możliwość wznowienia przesyłania pliku

Oto żądanie wznowienia przesyłania całego pliku PNG o wielkości 2 000 000 bajtów (bieżący przykład).

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 wyśle w odpowiedzi HTTP 201 Created oraz wszystkie metadane powiązane z tym zasobem. Jeśli początkowym żądaniem sesji możliwej do wznowienia było żądanie PUT, w przypadku aktualizacji istniejącego zasobu odpowiedź sukces będzie zawierać wartość 200 OK wraz ze wszystkimi metadanymi powiązanymi z tym zasobem.

Jeśli żądanie przesyłania zostanie przerwane albo otrzymasz od serwera odpowiedź HTTP 503 Service Unavailable lub inną odpowiedź 5xx, wykonaj czynności opisane w sekcji Wznawianie przerwanego przesyłania.


Prześlij plik we fragmentach

Dzięki możliwości wznowienia przesyłania możesz podzielić plik na fragmenty i wysłać serię żądań o przesłanie każdego fragmentu po kolei. Nie jest to preferowane rozwiązanie, ponieważ dodatkowe żądania wiążą się z kosztami wydajności i zasadniczo nie są potrzebne. Jeśli jednak chcesz zmniejszyć ilość danych przesyłanych w jednym żądaniu, konieczne może być ich podział na fragmenty. Jest to przydatne, gdy istnieje stały limit czasu dla poszczególnych żądań, podobnie jak w przypadku niektórych klas żądań Google App Engine. Pozwala też na przykład wyświetlać wskaźniki postępu przesyłania w starszych przeglądarkach, które nie obsługują postępu przesyłania domyślnie.

Jeśli przesyłasz dane we fragmentach, w przypadku przesyłania całych plików wymagany jest też nagłówek Content-Range oraz nagłówek Content-Length:

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

  • Content-Range: pokazuje, jakie bajty w przesyłanym pliku są przesyłane. Na przykład Content-Range: bytes 0-524287/2000000 pokazuje, że udostępniasz pierwsze 524 288 bajtów (256 x 1024 x 2) w pliku o wielkości 2 000 000 bajtów.

Przykład: żądanie wznowienia częściowego przesyłania pliku

Żądanie, które wysyła pierwsze 524 288 bajtów, może wyglądać tak:

PUT {session_uri} HTTP/1.1
Host: www.googleapis.com
Content-Length: 524288
Content-Type: image/png
Content-Range: bytes 0-524287/2000000

bytes 0-524288

Jeśli żądanie się powiedzie, serwer wyśle w odpowiedzi 308 Resume Incomplete oraz nagłówek Range, który określa łączną liczbę przechowywanych do tej pory bajtów:

HTTP/1.1 308 Resume Incomplete
Content-Length: 0
Range: bytes=0-524287

Użyj górnej wartości zwróconej w nagłówku Range, aby określić miejsce rozpoczęcia następnego fragmentu. Przejdź do PUT każdego fragmentu pliku, aż cały plik zostanie przesłany.

Jeśli żądanie PUT któregokolwiek fragmentu zostanie przerwane albo otrzyma z serwera odpowiedź HTTP 503 Service Unavailable lub jakąkolwiek inną odpowiedź 5xx, wykonaj czynności opisane w sekcji poświęconej wznawianiu przerwanego przesyłania. Zamiast przesyłać resztę pliku, po prostu kontynuuj przesyłanie fragmentów od tego momentu.

Ważne uwagi:

  • Pamiętaj, by użyć w odpowiedzi nagłówka Range, aby określić, od którego miejsca rozpocząć następny fragment. Nie zakładaj, że serwer otrzymał wszystkie bajty wysłane w poprzednim żądaniu.

  • Każdy identyfikator URI przesyłania ma ograniczony czas ważności i w końcu wygasa (w ciągu ok. 1 dnia, jeśli nie zostanie użyty). Z tego powodu najlepiej rozpocząć wznawianie przesyłania zaraz po uzyskaniu identyfikatora URI przesyłania i wznowić przerwane przesyłanie tuż po wystąpieniu przerwy.

  • Jeśli wyślesz żądanie z identyfikatorem sesji przesyłania, które wygasły, serwer zwróci kod stanu 404 Not Found. Jeśli w sesji przesyłania wystąpi nieodwracalny błąd, serwer zwraca kod stanu 410 Gone. W takich przypadkach musisz rozpocząć nowe przesyłanie z możliwością wznowienia, uzyskać nowy identyfikator URI przesyłania i rozpocząć przesyłanie od początku z wykorzystaniem nowego punktu końcowego.

Po zakończeniu przesyłania pliku serwer wysyła odpowiedź, używając parametru HTTP 201 Created wraz ze wszystkimi metadanymi powiązanymi z tym zasobem. Gdyby żądanie dotyczyło aktualizacji istniejącej encji, a nie tworzenia nowej, kod odpowiedzi HTTP miałby postać 200 OK.


Wznawianie przerwanego przesyłania

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

  1. Stan żądania. Aby sprawdzić bieżący stan przesyłania, wyślij puste żądanie PUT do identyfikatora URI przesyłania. Na potrzeby tego żądania 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ść plików to 2 000 000, ustaw Content-Range na */2000000. Jeśli nie znasz pełnego rozmiaru pliku, w polu Content-Range (Zakres treści) ustaw wartość */*.

  2. Sprawdzanie liczby przesłanych bajtów. Przetwarza odpowiedź z zapytania o stan. Serwer w odpowiedzi używa nagłówka Range, aby określić, jakie bajty odebrał do tej pory. Na przykład nagłówek Range o wartości 0-299999 oznacza, że otrzymano pierwsze 300 000 bajtów pliku.

  3. Prześlij pozostałe dane. Wiedząc już, gdzie wznowić żądanie, wyślij pozostałe dane lub bieżący fragment. Pamiętaj, że w każdym przypadku pozostałe dane musisz traktować jako oddzielny fragment, więc po wznowieniu przesyłania musisz wysłać nagłówek Content-Range.

Przykład: wznawianie przerwanego przesyłania

  1. Poproś o stan przesyłania. Podane niżej żądanie używa nagłówka Content-Range,aby wskazać,że bieżąca pozycja w pliku o wielkości 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ę przesłanych do tej pory bajtów. Odpowiedź serwera używa nagłówka Range, aby wskazać, że do tej pory odebrał pierwsze 43 bajty pliku. Górna wartość nagłówka Zakres służy do określenia miejsca rozpoczęcia wznowienia przesyłania.

HTTP/1.1 308 Resume Incomplete
Content-Length: 0
Range: 0-42
  1. Wznów przesyłanie od miejsca, w którym zostało przerwane. Kolejne żądanie wznowi przesyłanie, wysyłając pozostałe bajty pliku, zaczynając od 43 bajtów.
PUT {session_uri} HTTP/1.1
Content-Length: 1999957
Content-Range: bytes 43-1999999/2000000

bytes 43-1999999

Sprawdzone metody

Przy przesyłaniu multimediów warto znać sprawdzone metody postępowania z błędami.

  • Wznów lub ponów próbę przesyłania, które nie powiedzie się z powodu przerw w połączeniu lub błędów 5xx, w tym:

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

  • Inne rodzaje żądań nie powinny być obsługiwane przez wykładnicze ponawianie, ale nadal możesz spróbować ponownie wykonać wiele z nich. Jeśli chcesz to zrobić, ogranicz liczbę kolejnych prób. Na przykład kod może mieć maksymalnie 10 ponownych prób przed zgłoszeniem błędu.

  • Gdy przesyłasz dane z możliwością wznowienia, napraw błędy 404 Not Found i 410 Gone, rozpoczynając cały proces od początku.

Ponawianie wykładnicze

Wykładnicze ponawianie to standardowa strategia obsługi błędów w aplikacjach sieciowych, w której klient okresowo ponawia próbę nieudanego żądania w coraz dłuższym czasie. Jeśli duża liczba żądań lub duży ruch w sieci powoduje, że serwer zwraca błędy, dobrą strategią rozwiązywania takich problemów może być wykładnicze ponawianie. Z kolei nie sprawdza się przy rozwiązywaniu problemów z błędami niezwiązanymi z liczbą sieci lub czasem reakcji, takimi jak nieprawidłowe dane logowania lub błędy „Nie znaleziono pliku”.

Właściwe użycie wykładniczego ponowienia zwiększa wydajność wykorzystania przepustowości, zmniejsza liczbę żądań wymaganych do uzyskania skutecznej odpowiedzi oraz maksymalizuje przepustowość żądań w równoczesnych środowiskach.

Proces implementacji prostego, wykładniczego ponowienia jest następujący:

  1. Wyślij żądanie do interfejsu API.
  2. Otrzymasz odpowiedź HTTP 503, co oznacza, że należy ponowić żądanie.
  3. Zaczekaj 1 sekundę + random_number_milliseconds i spróbuj ponownie.
  4. Otrzymasz odpowiedź HTTP 503, co oznacza, że należy ponowić żądanie.
  5. Zaczekaj 2 sekundy + random_number_milliseconds i spróbuj ponownie.
  6. Otrzymasz odpowiedź HTTP 503, co oznacza, że należy ponowić żądanie.
  7. Zaczekaj 4 sekundy + random_number_milliseconds i spróbuj ponownie.
  8. Otrzymasz HTTP 503 response, co oznacza, że musisz ponowić żądanie.
  9. Zaczekaj 8 sekund + random_number_milliseconds i spróbuj ponownie.
  10. Otrzymasz HTTP 503 response, co oznacza, że musisz ponowić żądanie.
  11. Zaczekaj 16 sekund + random_number_milliseconds i spróbuj ponownie.
  12. Zatrzymaj. Zgłoś lub zarejestruj błąd.

Na powyższej liście random_number_milliseconds to losowa liczba milisekund nie mniejsza niż 1000. Jest to konieczne, ponieważ wprowadzenie niewielkiego opóźnienia losowego pozwala bardziej równomiernie rozłożyć obciążenie i uniknąć możliwości dodawania stempla na serwerze. Wartość parametru random_number_milliseconds musi być ponownie określona po każdym czasie oczekiwania.

Algorytm kończy działanie, gdy wartość n wynosi 5. Ten limit zapobiega nieskończonemu ponawianiu prób przez klientów i powoduje całkowite opóźnienie (około 32 sekundy) przed uznaniem żądania za „nieodwracalny błąd”. Większa maksymalna liczba ponownych prób jest odpowiednia, zwłaszcza jeśli trwa przesyłanie długiego materiału. Pamiętaj tylko, aby ustawić opóźnienie na mniej więcej niż minutę.

Przewodniki po bibliotece klienta interfejsu API