Funkcja przesyłania multimediów pozwala interfejsowi Display & Video 360 API przechowywać dane w chmurze i udostępniać je serwerowi. Możesz przesyłać m.in. zdjęcia, filmy, pliki PDF, pliki ZIP i inne rodzaje danych.
Przykłady w tym dokumencie pokazują wykorzystanie przesyłania multimediów w fikcyjnym interfejsie Farm API. Te same pojęcia mają jednak zastosowanie w przypadku interfejsu Display & Video 360 API.
Opcje przesyłania
Interfejs Display & Video 360 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 dla każdej metody, która obsługuje 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 różne sposoby. Za pomocą parametru żądania uploadType
określ używaną metodę.
- Proste przesyłanie:
uploadType=media
. Umożliwia szybkie przesyłanie mniejszych plików, np. o rozmiarze do 5 MB. - Przesyłanie wieloczęściowe:
uploadType=multipart
Aby szybko przesyłać mniejsze pliki i metadane, prześlij plik wraz z opisanymi metadanymi – wszystko w ramach jednego żądania. - Wznawianie przesyłania:
uploadType=resumable
. Umożliwia niezawodne przesyłanie danych, co jest szczególnie ważne w przypadku większych plików. Ta metoda używa żądania inicjowania sesji, które opcjonalnie może zawierać metadane. Jest to odpowiednia strategia dla większości aplikacji, ponieważ sprawdza się również w przypadku mniejszych plików i kosztuje jedno dodatkowe żądanie HTTP na przesłanie.
Do przesyłania multimediów używasz specjalnego identyfikatora URI. Metody obsługujące przesyłanie multimediów mają 2 punkty końcowe URI:
Identyfikator URI multimediów /upload. Format punktu końcowego przesyłania to standardowy identyfikator URI zasobów z prefiksem „/upload”. Używaj tego identyfikatora URI do przesyłania samych danych multimedialnych.
Przykład:
POST /upload/farm/v1/animals
Standardowy identyfikator URI zasobu dla metadanych. Jeśli zasób zawiera 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 /farm/v1/animals
Proste przesyłanie
Najprostszą metodą przesłania pliku jest przesłanie prostej prośby o jego przesłanie. Ta opcja jest dobrym rozwiązaniem, gdy:
- Plik jest na tyle mały, że jeśli nie uda się nawiązać połączenia, ponownie prześlij go w całości.
- Brak metadanych do wysłania. Może się tak zdarzyć, jeśli planujesz wysyłać metadane tego zasobu w osobnym żądaniu lub gdy żadne metadane nie są obsługiwane ani dostępne.
Aby użyć prostego przesyłania, wyślij żądanie POST
lub PUT
do identyfikatora URI /upload metody i dodaj parametr zapytania uploadType=media
. Na przykład:
POST https://www.googleapis.com/upload/farm/v1/animals?uploadType=media
Nagłówki HTTP używane podczas tworzenia prostego żądania przesyłania obejmują:
Content-Type
. Ustaw jeden z akceptowanych typów przesyłanych danych multimedialnych, które są określone w dokumentacji interfejsu API.Content-Length
. Ustaw liczbę bajtów, które przesyłasz. Nie jest wymagane, jeśli używasz kodowania fragmentów.
Przykład: proste przesyłanie
Poniższy przykład pokazuje wykorzystanie prostego żądania przesłania do fikcyjnego interfejsu Farm API.
POST /upload/farm/v1/animals?uploadType=media HTTP/1.1 Host: www.googleapis.com Content-Type: image/jpeg Content-Length: number_of_bytes_in_file Authorization: Bearer your_auth_token JPEG data
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 { "name": "Llama" }
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
. Jest to dobry wybór, jeśli wysyłane dane są wystarczająco małe, aby można było ponownie przesłać je w całości, gdy połączenie nie powiedzie się.
Aby korzystać z 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/farm/v1/animals?uploadType=multipart
Nagłówki HTTP najwyższego poziomu, których należy używać podczas tworzenia żądania przesyłania wieloczęściowego, to:
Content-Type
. Ustaw wartość jako wieloczęściową/powiązaną i uwzględnij ciąg granicy używany do identyfikowania części żądania.Content-Length
. Ustaw łączną liczbę bajtów w treści żądania. Część multimedialna w żądaniu musi być mniejsza niż maksymalny rozmiar pliku określony w tej metodzie.
Treść żądania ma format multipart/related
[RFC2387] i zawiera dokładnie 2 części. Części są określane ciągiem określającym granice, a na końcu końcowego ciągu granicznego znajdują się 2 łączniki.
Każda część żądania wieloczęściowego wymaga dodatkowego nagłówka Content-Type
:
- Część metadanych: musi być umieszczona jako pierwsza, a
Content-Type
musi pasować do jednego z akceptowanych formatów metadanych. - Część multimediów: musi być na drugiej pozycji, a
Content-Type
musi być zgodny z jednym z akceptowanych typów MIME multimediów stosowanych w metodzie.
Listę akceptowanych typów MIME multimediów dla poszczególnych metod oraz limitów rozmiarów przesyłanych plików znajdziesz w dokumentacji interfejsu API.
Uwaga: aby utworzyć lub zaktualizować tylko część metadanych bez przesyłania powiązanych danych, po prostu wyślij żądanie POST
lub PUT
do standardowego punktu końcowego zasobu: https://www.googleapis.com/farm/v1/animals
Przykład: przesyłanie wieloczęściowe
Przykład poniżej przedstawia wieloczęściowe żądanie przesyłania dla fikcyjnego interfejsu Farm API.
POST /upload/farm/v1/animals?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 { "name": "Llama" } --foo_bar_baz Content-Type: image/jpeg JPEG data --foo_bar_baz--
Jeśli żądanie się powiedzie, serwer zwróci kod stanu HTTP 200 OK
wraz ze wszystkimi metadanymi:
HTTP/1.1 200 Content-Type: application/json { "name": "Llama" }
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 przez błąd komunikacji. Jest to szczególnie przydatne, jeśli przesyłasz duże pliki, w przypadku których prawdopodobieństwo przerwy w działaniu sieci lub innej awarii przesyłania danych jest wysokie, np. podczas przesyłania z aplikacji mobilnej klienckiej. Funkcja może też zmniejszyć wykorzystanie przepustowości w przypadku awarii sieci, ponieważ nie trzeba ponownie uruchamiać dużych plików.
Aby włączyć przesyłanie z możliwością wznowienia:
- Rozpocznij sesję, którą można wznowić. Jeśli występują, wyślij początkowe żądanie do identyfikatora URI przesyłania zawierającego metadane.
- Zapisz identyfikator URI sesji możliwej do wznowienia. Zapisz identyfikator URI sesji zwrócony w odpowiedzi na pierwsze żądanie. Będziesz go używać w pozostałych żądaniach w tej sesji.
- Prześlij plik. Wyślij plik multimedialny do identyfikatora URI sesji możliwej do wznowienia.
Oprócz tego 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 otrzymanych, a następnie wznów przesyłanie od tego momentu.
Uwaga: identyfikator URI przesyłania wygasa po tygodniu.
Krok 1. Rozpocznij sesję z możliwością 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/farm/v1/animals?uploadType=resumable
Treść żądania jest pusta lub zawiera tylko metadane. W kolejnych żądaniach przenosisz faktyczną 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 dla przesyłanych danych, które mają być przesyłane w kolejnych żądaniach.X-Upload-Content-Length
. Ustaw liczbę bajtów przesyłanych danych, które mają być przesyłane w kolejnych żądaniach. Jeśli w momencie przesyłania żądania długość jest nieznana, możesz pominąć ten nagłówek.- W przypadku podawania metadanych:
Content-Type
. Ustawiany jest zgodnie z typem danych metadanych. Content-Length
. Ustaw liczbę bajtów w treści tego początkowego żądania. Nie jest wymagane, jeśli używasz kodowania fragmentów.
Listę akceptowanych typów MIME multimediów dla poszczególnych metod oraz limitów rozmiarów przesyłanych plików znajdziesz w dokumentacji interfejsu API.
Przykład: żądanie zainicjowania sesji możliwe do wznowienia
Przykład poniżej pokazuje, jak zainicjować sesję z możliwością wznowienia dla fikcyjnego interfejsu Farm API.
POST /upload/farm/v1/animals?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/jpeg X-Upload-Content-Length: 2000000 { "name": "Llama" }
Uwaga: w przypadku początkowego wznowienia aktualizacji bez metadanych pozostaw treść żądania pustą i ustaw nagłówek Content-Length
na 0
.
Następna sekcja zawiera informacje na temat postępowania z odpowiedzią.
Krok 2. Zapisz identyfikator URI sesji możliwej do wznowienia
Jeśli żądanie inicjowania sesji się powiedzie, serwer interfejsu API w odpowiedzi wyświetli kod stanu HTTP 200 OK
. Dodatkowo zawiera nagłówek Location
, który określa identyfikator URI sesji, który można wznowić. Nagłówek Location
, widoczny w przykładzie poniżej, zawiera fragment parametru zapytania upload_id
, który podaje unikalny identyfikator przesyłania używany w tej sesji.
Przykład: odpowiedź na rozpoczęcie sesji z możliwością wznowienia
Oto odpowiedź na prośbę z kroku 1:
HTTP/1.1 200 OK Location: https://www.googleapis.com/upload/farm/v1/animals?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 będziesz używać jako punktu końcowego HTTP podczas 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.
Krok 3: prześlij plik
Aby przesłać plik, wyślij żądanie PUT
na identyfikator URI przesyłania uzyskany w poprzednim kroku. Takie żądanie ma format:
PUT session_uri
Nagłówki HTTP używane przy tworzeniu żądań wznowienia przesyłania plików obejmują element Content-Length
. Wpisz w tym polu liczbę bajtów, które przesyłasz w ramach tego żądania, czyli zazwyczaj jest to rozmiar przesyłanego pliku.
Przykład: prośba o wznawianie przesłania pliku
Oto możliwe do wznowienia żądanie przesłania całego pliku JPEG o wielkości 2 000 000 bajtów z bieżącego przykładu.
PUT https://www.googleapis.com/upload/farm/v1/animals?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1 Content-Length: 2000000 Content-Type: image/jpeg bytes 0-1999999
Jeśli żądanie się powiedzie, serwer w odpowiedzi wyświetli HTTP 201 Created
wraz ze wszystkimi metadanymi powiązanymi z tym zasobem. Jeśli początkowym żądaniem sesji możliwej do wznowienia było żądanie PUT
, w celu zaktualizowania istniejącego zasobu odpowiedź powołana to 200 OK
wraz z wszelkimi metadanymi powiązanymi z tym zasobem.
Jeśli żądanie przesyłania zostało przerwane albo otrzymasz od serwera odpowiedź HTTP 503 Service Unavailable
lub inną odpowiedź 5xx
, wykonaj czynności opisane w sekcji Wznawianie przerwanego przesyłania.
Przesyłanie pliku partiami
Przesyłanie z możliwością wznowienia pozwala podzielić plik na fragmenty i wysłać serię żądań o przesłanie poszczególnych fragmentów. Nie jest to preferowane podejście, ponieważ dodatkowe żądania wiążą się z kosztami wydajności i zasadniczo nie są potrzebne. Może być jednak konieczne zastosowanie podziału na fragmenty, aby zmniejszyć ilość danych przesyłanych w jednym żądaniu. Jest to przydatne, gdy istnieje stały limit czasu dla poszczególnych żądań, jak ma to miejsce w przypadku niektórych klas żądań Google App Engine. W ten sposób możesz też na przykład wyświetlać wskaźniki postępu przesyłania w starszych przeglądarkach, które domyślnie nie obsługują tego procesu.
Wznawianie przerwanego przesyłania
Jeśli żądanie przesyłania zostanie zakończone przed otrzymaniem odpowiedzi lub jeśli otrzymasz z serwera odpowiedź HTTP 503 Service Unavailable
, musisz wznowić przerwane przesyłanie. Aby to zrobić:
- Stan żądania. Sprawdzaj bieżący stan przesyłania, wysyłając puste żądanie
PUT
do identyfikatora URI przesyłania. W przypadku tego żądania nagłówki HTTP powinny zawierać nagłówekContent-Range
wskazujący, że bieżąca pozycja w pliku jest nieznana. Jeśli na przykład łączna długość pliku wynosi 2 000 000, możesz ustawićContent-Range
na*/2000000
. Jeśli nie znasz pełnego rozmiaru pliku, ustawContent-Range
na*/*
.Uwaga: możesz poprosić o stan między poszczególnymi fragmentami, nie tylko wtedy, gdy przesyłanie zostało przerwane. Jest to przydatne na przykład wtedy, gdy chcesz wyświetlać wskaźniki postępu przesyłania w starszych przeglądarkach.
- Sprawdzanie liczby przesłanych bajtów. Przetwarzanie odpowiedzi 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łówekRange
o wartości0-299999
oznacza, że otrzymano pierwsze 300 000 bajtów pliku. - Prześlij pozostałe dane. Teraz, gdy wiesz już, gdzie wznowić żądanie, wyślij pozostałe dane lub bieżący fragment. Pamiętaj, że w obu przypadkach pozostałe dane musisz traktować jako osobny 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.
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 liczbę bajtów przesłanych do tej pory z odpowiedzi.
Odpowiedź serwera używa nagłówka Range
do wskazania, że odebrał pierwsze 43 bajty pliku. Użyj górnej wartości nagłówka Range
, aby określić miejsce rozpoczęcia wznowienia przesyłania.
HTTP/1.1 308 Resume Incomplete Content-Length: 0 Range: 0-42
Uwaga: po zakończeniu przesyłania odpowiedź o stanie może być 201 Created
lub 200 OK
. Może się tak zdarzyć, jeśli połączenie zostało przerwane po przesłaniu wszystkich bajtów, ale przed otrzymaniem odpowiedzi od serwera przez klienta.
3) Wznów przesyłanie od miejsca, w którym zostało przerwane.
To żądanie wznowi przesyłanie, wysyłając pozostałe bajty pliku (począwszy od 43 bajtów).
PUT {session_uri} HTTP/1.1 Content-Length: 1999957 Content-Range: bytes 43-1999999/2000000 bytes 43-1999999
Sprawdzone metody
Podczas przesyłania multimediów warto znać sprawdzone metody postępowania z błędami.
- Wznów lub ponów próbę przesyłania, jeśli nie uda się je przesłać 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
- Użyj strategii wykładniczego ponowienia, jeśli podczas wznawiania lub ponawiania żądań przesłania zwracany jest dowolny błąd serwera
5xx
. Te błędy mogą wystąpić, gdy serwer jest przeciążony. Wykładnicze opóźnienie może pomóc złagodzić tego typu problemy w okresach dużej liczby żądań lub dużego ruchu w sieci. - Żądania innych rodzajów nie powinny być obsługiwane przez wykładnicze ponawianie, ale nadal możesz ponawiać próby wykonania kilku z nich. Ogranicz liczbę ponownych prób. Kod może na przykład zostać ograniczony do 10 ponownych prób przed zgłoszeniem błędu.
- Podczas wznawiania przesyłania możesz usunąć błędy
404 Not Found
i410 Gone
, zaczynając od początku.
Wykładniczy czas ponowienia
Wykładniczy czas ponowienia to standardowa strategia obsługi błędów w aplikacjach sieciowych, w której klient przez dłuższy czas ponawia próbę nieudanego żądania. Jeśli duża liczba żądań lub duży ruch w sieci powoduje, że serwer zwraca błędy, dobrym rozwiązaniem w przypadku tych błędów może być wykładnicze ponawianie. Nie sprawdza się natomiast w przypadku błędów niezwiązanych z liczbą sieci lub czasem odpowiedzi, takich jak nieprawidłowe dane uwierzytelniające lub błędy „Nie znaleziono pliku”.
Poprawne wykorzystanie wykładniczego ponowienia zwiększa wydajność wykorzystania przepustowości, zmniejsza liczbę żądań wymaganych do uzyskania pomyślnej odpowiedzi i maksymalizuje przepustowość żądań w środowiskach równoczesnych.
Proces implementacji prostego wykładniczego ponowienia jest następujący:
- Wyślij żądanie do interfejsu API.
- Otrzymasz odpowiedź
HTTP 503
, co oznacza, że musisz ponowić żądanie. - Zaczekaj 1 sekundę + random_number_milliseconds i spróbuj ponownie.
- Otrzymasz odpowiedź
HTTP 503
, co oznacza, że musisz ponowić żądanie. - Zaczekaj 2 sekundy + random_number_milliseconds i spróbuj ponownie wysłać żądanie.
- Otrzymasz odpowiedź
HTTP 503
, co oznacza, że musisz ponowić żądanie. - Zaczekaj 4 sekundy + random_number_milliseconds i spróbuj ponownie.
- Otrzymasz odpowiedź
HTTP 503
, co oznacza, że musisz ponowić żądanie. - Zaczekaj 8 sekund + random_number_milliseconds i spróbuj ponownie.
- Otrzymasz odpowiedź
HTTP 503
, co oznacza, że musisz ponowić żądanie. - Zaczekaj 16 sekund + random_number_milliseconds i spróbuj ponownie.
- Zatrzymaj. Zgłoś lub zarejestruj błąd.
W powyższym procesie random_number_milliseconds to losowa liczba milisekund mniejszą lub równą 1000. Jest to konieczne, ponieważ wprowadzenie niewielkiego opóźnienia losowego pozwala bardziej równomiernie rozłożyć obciążenie i uniknąć możliwości oznaczenia serwera śladami. Wartość random_number_milliseconds musi być ponownie zdefiniowana po każdym oczekiwaniu.
Uwaga: czas oczekiwania zawsze wynosi (2 ^ n) + losowa_liczba_milisekund, gdzie n to monotonicznie rosnąca liczba całkowita zdefiniowana jako 0. Liczba całkowita n zwiększa się o 1 przy każdej iteracji (każdym żądaniu).
Algorytm kończy działanie, gdy wartość n wynosi 5. Ten limit zapobiega nieskończonemu ponawianiu prób klientów i powoduje całkowite opóźnienie (około 32 sekundy) przed uznaniem żądania za „nieodwracalny błąd”. Można użyć większej liczby ponownych prób, zwłaszcza jeśli trwa przesyłanie długiego czasu. Pamiętaj tylko, by ustawić rozsądną wartość opóźnienia na mniej niż minutę.