Jan Inowolski - ji262511 Protokół komunikacji YouPAY! Wersja 1 Spis treści: * Streszczenie * Cele * Model komunikacji * Założenia * Format komunikatów * Pomocnicze typy danych * Komunikaty specjalne * Komunikaty etapu informacyjnego * Komunikaty etapu licytacji * Opis komunikacji * Komunikacja specjalna i sytuacje wyjątkowe * Komunikacja etapu informacyjnego * Komunikacja etapu licytacji * Opis stanów licytacji po stronie klienta * Opis stanów licytacji po stronie serwera * Schemat komunikacji * Numery === Streszczenie === Dokument ten opisuje protokół obsługi aukcji internetowych. Komunikacja odbywa się za pomocą bezpośrednich połączeń. Każdy użytkownik może otwierać swoje aukcje lub brać udział w aukcjach otwartych przez innych użytkowników. === Cele === Protokół ma zapewnić przekazywanie informacji o przedmiotach wystawionych na aukcje oraz obsługiwać przebieg aukcji od jej otwarcia i rozsyłania informacji o przedmiocie poprzez licytację aż do zamknięcia licytacji. === Model komunikacji === Komunikacja przebiega dwuetapowo: I. Etap informacyjny -- uczestnik aukcji może zapytać sprzedawcę o opisy wystawionych przedmiotów, zadać dodatkowe pytania i otrzymać na nie odpowiedzi. Etap ten nie zobowiązuje stron do niczego, nie ma potrzeby przekazywania danych osobowych potencjalnego nabywcy ani sprzedawcy. II. Etap licytacji -- uczestnik zapisuje się do licytacji i następuje wymiana danych osobowych między sprzedawcą i uczestnikiem aukcji. Gdy użytkownik jest zapisay do licytacji, może zgłaszać propozycje swojej ceny przedmiotu. Informacje o przebiegu aukcji są przekazywane wszystkim zapisanym. Sprzedawca może w dowolnym momencie zakończyć aukcję, czyli nawiązać umowę z kupującym. Na etapie licytacji można w pełni korzystać z funkcjonalności etapu informacyjnego. Aukcja trwa od momentu, gdy informacje o przedmiocie są dostępne dla klientów, a kończy się wraz z wysłaniem opisanego dalej komunikatu FINISH_MSG. Powyższy schemat stanowi typowy sposób korzystania z protokołu. Szczegółowa specyfikacja i obsługa nietypowych sytuacji zostanie opisana dalej. === Założenia === Protokół działa w warstwie aplikacji. Wszystkie komunikaty przesyłane są z wykorzystaniem protokołu TCP. Serwer jest wystawiony przez użytkownika prowadzącego aukcję (sprzedającego), a klientami są programy potencjalnych nabywców przedmiotu. Zakładamy, że uczestnik aukcji zna adres i numer portu serwera, z którym chce się połączyć. Domyślnym numerem portu jest 2033. Połączenie jest nawiązywane przez klienta jednorazowo na cały proces komunikacji z serwerem. W przypadku przerwania połączenia TCP na etapie licytacji, klient ponownie przesyła prośbę o włączenie do licytacji, podając swój identyfikator sprzed przerwania połączenia.
Wszystkie komunikaty są asynchroniczne, tzn. gdy oczekujemy na przybycie komunikatu typu X, a w międzyczasie przyjdzie komunikat Y, to komunikat Y należy poprawnie obsłużyć i dalej oczekiwać na przybycie komunikatu typu X. Wraz z powstawaniem nowych wersji protokołu, komunikacja pomiędzy programami obsługującymi różne wersje będzie się odbywać we wspólnej, wynegocjowanej przez serwer i klienta wersji. === Format komunikatów === Komunikaty liczbowe są przesyłane w sieciowym porządku oktetów. Wszystkie napisy, o ile nie jest określone inaczej, są przesyłane w kodowaniu UTF-8. ===== Pomocnicze typy danych ===== 1. Nagłówek każdego komunikatu: { octet [2] uint8 uint8 magick_number; protocol_version; msg_type; magick_number - Pole zawierające kolejno znaki ASCII 'YP' protocol_version - Wersja protokołu równa numerowi PROTOCOL_VERSION msg_type - Wartość identyfikująca typ komunikatu. Specyfikacja każdego typu komunikatu definiuje odpowiednio tę wartość. 2. Krótki opis przedmiotu ITEM_SHORT_T { uint32 octet [3] octet [247] item_price; item_price_curr; short_description; item_id - identyfikator przedmiotu wystawionego na aukcję item_price - aktualna cena przedmiotu item_price_curr - trzyliterowe (ASCII) oznaczenie waluty, w jakiej odbywa się licytacja, np. 'PLN', 'USD'. short_description - napis zawierający krótki opis przedmiotu 3. Załącznik ATTACHMENT_T { uint32 attachment_length; octet [attachment_length] content; 'content' w pierwszych oktetach zawiera napis określający typ MIME przesyłanego pliku, następnie znak końca linii '\n', następnie zawartość przesyłanego pliku. 4. Parametry aukcji AUCTION_INFO_T { user_id; uint32 item_price; header.msg_type musi być zdefiniowany oddzielnie dla każdego komunikatu wykorzystującego tę strukturę. item_id - identyfikator przedmiotu, którego dotyczy komunikat user_id - użytkownik, z którym związana jest akcja - pole musi być zdefiniowane oddzielnie dla każdego typu komunikatu item_price - o ile nie zdefiniowane inaczej, bieżąca cena przedmiotu
===== Komunikaty specjalne ===== S1. Prośba o powtórzenie komunikatu w starszej wersji protokołu REP_QUERY_MSG { header.msg_type = REP_QUERY_MSGTYPE Komunikat jest wysyłany, gdy przybędzie komunikat w nieobsługiwanej wersji protokołu. S2. Brak przedmiotu o podanym identyfikatorze ITEM_NOT_FOUND_MSG { header.msg_type = ITEM_NOT_FOUND_MSGTYPE item_id - identyfikator przedmiotu, którego dotyczył komunikat klienta Komunikat jest wysyłany zawsze, gdy klient wyśle komunikat związany z nieistniejącym przedmiotem. S3. Prośba o echo (na potrzeby testów lub wyszukiwania serwerów) KNOCK_KNOCK_MSG { header.msg_type = KNOCK_KNOCK_MSGTYPE Komunikat jest przeznaczony do sprawdzenia, czy serwer aukcji jest aktywny, z uniknięciem przesyłania niepotrzebnych danych. ===== Komnikaty etapu informacyjnego ===== I1. Zapytanie o listę wystawionych przedmiotów. LIST_QUERY_MSG { header.msg_type = LIST_QUERY_MSGTYPE I2. Lista przedmiotów LIST_MSG { items_number; ITEM_SHORT_T [items_number] item_description; header.msg_type = LIST_MSGTYPE I3. Zapytanie o opis przedmiotu ITEM_QUERY_MSG { header.msg_type = ITEM_QUERY_MSGTYPE item_id - identyfikator przedmiotu, którego klient chce otrzymać opis
I4. Opis przedmitu ITEM_DESCRIPTION_MSG { uint32 octet [3] octet [247] octet [desc_length] item_price; item_price_curr; short_description; desc_length; description header.msg_type = ITEM_DESCRIPTION_MSGTYPE; item_id - identyfikator przedmiotu item_price - bieżąca cena przedmiotu item_price_curr - trzyliterowe (ASCII) oznaczenie waluty, w jakiej odbywa się licytacja, np. 'PLN', 'USD'. short_description - napis zawierający krótki opis przedmiotu description - napis zawierający pełny opis przedmiotu I5. Dodatkowe pytanie o przedmiot ITEM_QUESTION_MSG { question_id; question_length; octet [question_length] question; header.msg_type = ITEM_QUESTION_MGTYPE item_id - identyfikator przedmiotu, którego dotyczy pytanie question_id - identyfikator pytania, generowany w dowolny sposób przez klienta - klient nie musi zapewnić unikalności tego numeru question - napis zawierający treść pytania I6. Odpowiedź na dodatkowe pytanie o przedmiot ITEM_REPLY_MSG { question_id; reply_length; octet [reply_length] reply; uint8 attachment_number; ATTACHMENT_T [attachment_number] attachment; header.msg_type = ITEM_REPLY_MSGTYPE item_id - identyfikator przedmiotu, którego dotyczy pytanie question_id - identyfikator pytania, na które jest przesyłana odpowiedź reply - napis zawierający odpowiedź na pytanie attachment - załączniki odpowiedzi
===== Komunikaty etapu licytacji ===== L1. Prośba o przyjęcie do aukcji MEMBER_REQUEST_MSG { user_id; octet [256] user_personal_data; header.msg_type = MEMBER_REQUEST_MSGTYPE item_id - identyfikator przedmiotu, do licytacji którego chce przystąpić klient user_id - identyfikator użytkownika (podawany po przerwaniu połączenia) lub zero, jeśli użytkownik prosi o przyznanie nowego numeru user_personal_data - napis zawierający dane osobowe klienta L2. Przyjęcie do aukcji YOUR_ID_MSG { octet [256] user_id; host_personal_data; header.msg_type = YOUR_ID_MSGTYPE item_id - identyfikator przedmiotu, do aukcji którego został przyjęty klient user_id - identyfikator przyznany użytkownikowi na potrzeby tej aukcji. Serwer musi w dowolny sposób zapewnić unikalność tego numeru dla każdego klienta. Klient nie musi otrzymać identycznych identyfikatorów dla licytacji różnych przedmiotów. Zabronione jest przyznanie użytkownkowi identyfikatora zerowego. host_personal_data - napis zawierający dane osobowe sprzedającego L3. Informacja o bieżącej ofercie OFFER_INFO_MSG: AUCTION_INFO_T; header.msg_type = OFFER_INFO_MSGTYPE user_id - identyfikator użytkownika, który złożył ofertę item_price - najnowsza cena przedmiotu, oferowana przez wymienionego wyżej użytkownika L4. Propozycja oferty OFFER_MSG: AUCTION_INFO_T; header.msg_type = OFFER_MSGTYPE user_id - identyfikator użytkownika, który składa ofertę item_price - oferowana cena L5. Akceptacja oferty ACCEPT_MSG: AUCTION_INFO_T; header.msg_type = ACCEPT_MSGTYPE user_id - identyfikator użytkownika, który składał ofertę item_price - potwierdzenie (powtórzenie) ceny użytkownika
L6. Odrzucenie oferty REJECT_MSG { AUCTION_INFO_T uint8 info; description; info.header.msg_type = REJECT_MSGTYPE info.user_id - identyfikator użytkownika, na którego ofertę odpowiada komunikat info.item_price - bieżąca cena przedmiotu description: - REJECT_BETTER_OFFER - istnieje już lepsza oferta (aktualna cena dostępa w polu info.item_price) - REJECT_AUCTION_CLOSED - aukcja zakończona L7. Zakończenie aukcji FINISH_MSG: AUCTION_INFO_T; header.msg_type = FINISH_MSGTYPE user_id - identyfikator użytkownika, który wygrał aukcję item_price - wylicytowana cena === Opis komunikacji === ===== Komunikacja specjalna i sytuacje wyjątkowe ===== 1. Negocjacja wersji protokołu: W odpowiedzi na każdy komunikat wysłany w nieobsługiwanej wersji protokołu (pole protocol_version) należy wysłać komunikat REP_QUERY_MSG. Pole protocol_version należy ustawić na obsługiwany numer wersji protokołu, nie wyższy niż zaproponowany przez drugą stronę. Każda implementacja musi obsługiwać przynajmniej wersję 1 protokołu. (spójrzmy na przypadek: implementacja A obsługuje wersje 1,3,5,7; implementacja B obsługuje 1,2,4,6,8 - po krótkim dialogu zostanie wynegocjowana wersja 1 protokołu) 2. Wszystkie komunikaty, które nie zawierają odpowiednio ustawionego pola magick_number są odrzucane bez żadnej informacji zwrotnej dla wysyłającego. Nie ma obowiązku logowania informacji o nieprawidłowych pakietach. 3. Prośba o echo: Natychmiast po otrzymaniu komunikatu KNOCK_KNOCK_MSG należy odpowiedzieć takim samym komunikatem. Przesłanie komunikatu jest gwarantowane raz na połączenie, a dla kolejnych zapytań implementacja może zdefiniować dowolną politykę odpowiadania lub nie. Implementacja musi być odporna na niepoprawnie zaimplementowanych klientów, którzy zawsze bezwarunkowo odpowiadają na komunikat prośby o echo (cykl odpowiedzi). 4. W przypadku niedostarczenia istotnych komunikatów, tj. w szczególności OFFER_MSG, ACCEPT_MSG, REJECT_MSG, FINISH_MSG, protokół powinien powiadomić użytkownika o zaistniałej sytuacji (w interfejsie programistycznym, np. poprzez funkcję callback). Implementacja może zostać rozszerzona o powiadamianie użytkownika o innych błędach komunikacji. ===== Komunikacja etapu informacyjnego ===== 1. Pobranie listy przedmiotów wystawionych na aukcję: - klient wysyła komunikat LIST_QUERY_MSG - serwer odpowiada komunikatem LIST_MSG 2. Pobranie opisu przedmiotu: - klient wysyła komunikat ITEM_QUERY_MSG - serwer odpowiada komunikatem ITEM_DESCRIPTION_MSG lub w przypadku błędnego identyfikatora, ITEM_NOT_FOUND_MSG 3. Uzyskanie odpowiedzi na dodatkowe pytanie dotyczące przedmiotu: - klient wysyła komunikat ITEM_QUESTION_MSG - serwer odpowiada komunikatem ITEM_REPLY_MSG lub w przypadku błędnego identyfikatora, ITEM_NOT_FOUND_MSG Informacje o przedmiocie są dostępne do zakończenia aukcji, tzn. po zakończeniu aukcji przedmiot nie pojawia się na liście przesyłanej komunikatem
LIST_MSG, a zapytania ITEM_QUERY_MSG i ITEM_QUESTION_MSG powodują odpowiedź ITEM_NOT_FOUND_MSG ===== Komunikacja etapu licytacji ===== ======= Opis stanów licytacji po stronie klienta ======= Diagram przedstawia stany klienta w trakcie etapu licytacji. Diagram dotyczy licytacji jednego przedmiotu. Na diagramie w następujący sposób są oznaczane: >KOMUNIKATY_WYCHODZĄCE> oraz <KOMUNIKATY_PRZYCHODZĄCE< >MEMBER_REQUEST_MSG> \ / <YOUR_ID_MSG< \ / +-------------------+,--->--->------> MEMBER_STATE ----------. +-------------------+ `------------' <OFFER_INFO_MSG< >OFFER_MSG> <REJECT_MSG< \ / +----------------+ `----------- WAITING_STATE +----------------+ <ACCEPT_MSG< <OFFER_INFO_MSG< \ / +---------------+ `--------------- WINNING_STATE +---------------+ <FINISH_MSG< <FINISH_MSG< \ / \ / +---------------------------------+ FINISH_STATE +---------------------------------+ * Wysłany w dowolnym momencie komunikat z serwera FINISH_MSG lub ITEM_NOT_FOUND powoduje przejście do stanu FINISH_STATE. MEMBER_STATE - klient jest zapisany do licytacji, ale jego ewentualna oferta nie jest najwyższa WAITING_STATE - klient wysłał ofertę i oczekuje na jej akceptację WINNING_STATE - oferta klienta jest najwyższa FINISH_STATE - licytacja jest zakończona - wraz z zakończeniem licytacji przestajemy mówić, że 'użytkownik jest zapisany do licytacji'.
======= Opis stanów licytacji po stronie serwera ======= +------------------+ PREPARED_STATE +------------------+ przejście po poleceniu użytkownika \ / +------------------+ <<<<< AUCTION_STATE >>>>> komunikacja z klientem +------------------+ <<<<< zapytanie-odpowiedź zgodnie z opisanym niżej >>>>> schematem przejście po poleceniu użytkownika >FINISH_MSG> \ / +------------------+ FINISHED_STATE +------------------+ PREPARED_STATE - aukcja jest przygotowana w protokole, ale nie jest jeszcze widoczna dla klientów AUCTION_STATE - informacje o aukcji są widoczne dla klientów, trwa licytacja FINISHED_STATE - aukcja jest zakończona, informacje nie są widoczne dla klientów (odpowiedzią na każde pytanie o dany przedmiot jest ITEM_NOT_FOUND_MSG. ======= Schemat komunikacji ======= Schemat dotyczy stanu licytacji AUCTION_STATE po stronie serwera oraz kończenia licytacji. Serwer odpowiada komunikatem ITEM_NOT_FOUND_MSG na każdy komunikat klienta zawierający niepoprawny identyfikator przedmiotu. 1. Dołączanie klienta do licytacji: - klient wysyła komunikat MEMBER_REQUEST_MSG - serwer odpowiada komunikatem YOUR_ID_MSG 2. Wysłanie oferty: - klient wysyła komunikat OFFER_MSG - serwer odpowiada klientowi komunikatem ACCEPT_MSG lub REJECT_MSG w przypadku odpowiednio zaakceptowania oferty (oferta przebija starą cenę) lub odrzucenia oferty (oferta nie przebija starej ceny lub licytacja już się zakończyła). Brak odpowiedzi po czasie ustalonym w implementacji klienta zostaje zinterpretowany jako odrzucenie oferty. - serwer wysyła do wszystkich zapisanych do licytacji komunikat OFFER_INFO_MSG zawierający informację o przebiciu oferty 3. Zakończenie aukcji: - serwer na żądanie użytkownika rozsyła do wszystkich zapisanych na aukcję komunikat FINISH_MSG. Klient ropoznaje, czy wygrał aukcję na podstawie pola user_id - jeżeli wartość zgadza się z identyfikatorem przyznanym na początku licytacji, to wygrał aukcję. Rozesłanie FINISH_MSG z polem user_id = 0 oznacza, że żaden klient nie wygrał aukcji. === Numery === PROTOCOL_VERSION = 1 REP_QUERY_MSGTYPE = 201 ITEM_NOT_FOUND_MSGTYPE = 202 KNOCK_KNOCK_MSGTYPE = 255 LIST_QUERY_MSGTYPE = 1 LIST_MSGTYPE = 2 ITEM_QUERY_MSGTYPE = 3 ITEM_DESCRIPTION_MSGTYPE = 4 ITEM_QUESTION_MGTYPE = 5 ITEM_REPLY_MSGTYPE = 6 MEMBER_REQUEST_MSGTYPE = 101 YOUR_ID_MSGTYPE = 102 OFFER_INFO_MSGTYPE = 103 OFFER_MSGTYPE = 104 ACCEPT_MSGTYPE = 105 REJECT_MSGTYPE = 106 FINISH_MSGTYPE = 107