System Rozproszone Komunikator Dokumentacja Maciej Muszkowski Jakub Narloch
Wymagania Zgodnie ze wstępnymi założeniami komunikator musi, realizowad następujące funkcje: 1. Jest oparty o model Peer2Peer, nie istnieje pojedynczy serwer centralny. Każdy z komunikatorów pełni funkcje zarówno serwera jak i klienta. 2. Przesyłanie publicznych wiadomości do wszystkich podłączonych komunikatorów. 3. Przesyłanie prywatnej wiadomości do wybranego adresata. 4. Komunikator wyświetla informację o tym, że ktoś w danej chwili pisze wiadomośd. 5. Przechowuje historię wiadomości wszystkich innych komunikatorów i pozwala ją w dowolnej chwili wyświetlid. 6. W przypadku rozłączenia się lub awarii po ponownym podłączeniu historia wiadomości jest synchronizowana. 7. Jeżeli nastąpi awaria, któregoś z węzłów i sied ulegnie podziałowi pozostałe komunikatory powinny byd w stanie na nowo nawiązad połączenie ze sobą. Protokół Protokół komunikacji został oparty o TCP, który zapewnia niezawodnośd. Format przesyłanych wiadomości został utworzony na bazie JSON. Poniżej wyspecyfikowane wszystkie rodzaje przesyłanych wiadomości wraz z opisem znaczenia ich pól oraz przykładami. Base: : pól: {"from_ipv4": "adres", "from_port": port} Komunikat base, stanowi bazowy typ wiadomości, wszystkie pozostałe wiadomości dziedziczą po nim jego pola. Pola from_ipv4 i port jednoznacznie identyfikują nadawcę w sieci. Komunikat Base nie jest przekazywany pomiędzy komunikatorami. Message: : {"from_ipv4": adres", "from_port": port, "time_info": wektor czasu, "msg_from_ipv4 : adres, "msg_from_port": port, "msg_to_ipv4": "adres", "msg_to_port": port, "message": "wiadomość" }
pól: Message, służy do przesyłania wiadomości pomiędzy użytkownikami. Każda z wiadomości zawiera aktualny czas wektorowy ze stanem wiedzy danego komunikatora o innych procesach. W momencie wysyłania wiadomości czas wektorowy w pozycji odpowiadającej nadawcy, jest zwiększany o 1. Wszystkie wiadomości, które zawierają adres msg_to_ipv4 ustawiony na 0.0.0.0, są traktowane, jako wiadomości publiczne i przesyłane do wszystkich komunikatorów. Wiadomości prywatne natomiast posiadają określonego odbiorcę wiadomości. Ponieważ wiadomości są rozsyłane po całej sieci, istniała potrzeba identyfikacji nadawcy wiadomości, dlatego dodano dwa pola msg_from_ipv4 oraz msf_from_port wskazujące na osobę, która wysłała wiadomośd. Pola from_ipv4 natomiast zawierają informację o tym, kto rozpowszechnia tą wiadomośd dalej. Wiadomośd message jest przesyłana w formacie UTF-8 w celu rozwiązania kwestii kodowania znaków diakrytycznych. time_info Zawiera czas wektorowy danego komunikatora i jego wiedzę o czasie logicznym innych komunikatorów. msg_from_ipv4 Adres IP nadawcy wiadomości. msg_from_port Port nadawcy wiadomości. msg_to_ipv4 Adres IP odbiorcy, zawiera 0.0.0.0, w przypadku wiadomości publicznych. msg_to_port Port odbiorcy, zawiera 0, w przypadku wiadomości publicznych. message Treśd wiadomości. Status: : pól: {"from_ipv4": "adress", "from_port": port, "status_ipv4": "adres", "status_port": port, "status": status"} Wiadomośd status, służy do przesyłania informacje o zmianie statusu użytkownika, czy jest on dostępny czy też się rozłączył. Pole status może zawierad dwie wartości: online lub offline. Status jest przesyłany przez każdy komunikator, który podłącza się do sieci (online). W momencie odłączania, się komunikator przesyła status offline. status_ipv4 Identyfikuję adres komunikatora, który przesyła informację o statusie. status_port Identyfikuję port komunikatora, który przesyła informację o statusie. status Status, może przyjmowad tylko dwie wartości online i offline.
MyIP: : pól: { "from_ipv4": adres", "from_port": port, "my_ipv4": "adres", "my_port": port} Wiadomośd MyIP, jest przesyłana jako pierwsza w momencie nawiązania nowego połączenia pomiędzy dwoma węzłami, służy ona do identyfikacji połączonych do siebie komunikatorów. my_ipv4 Zawiera adres IP nowo podłączonego węzła. my_port Zawiera port nowo podłączonego węzła. Backup: : pól: { "from_ipv4": "adress", "from_port": port, "backup_ipv4": "adress", "backup_port": port} Ze względu na przyjętą topologię sieci oraz mechanizm podłączania się do innych węzłów, w celu obsługi awarii innych konieczne było zdefiniowanie wiadomości, która będzie definiowała backup (węzeł zastępczy dla danego węzła). Backup jest przesyłany w momencie nawiązania nowego połączenia. Wiadomośd ta jest przesyłana wyłącznie przez serwer, do którego dany komunikator się podłączył. W przypadku, gdy węzeł który został wyznaczony za backup odłączy się ulegnie awarii istnieje koniecznośd wyznaczenia backup-a na nowo. backup_ipv4 Adres IP węzła będącego backup-em. backup_port Port węzła będącego backup-em.
Algorytmy i zastosowane rozwiązania Topologia sieci: W ramach tego projektu zastosowano topologię drzewa tzn. każdy z węzłów w danej chwili może się podłączyd wyłącznie do jednego węzła, sam natomiast, może przyjąd dowolną ilośd połączeo. Rozwiązanie to ma na celu wykluczenie cykli w tak zbudowanej sieci. Podłączenie się nowego węzła: W celu podłączenia się do innego węzła wymagana jest znajomośd adresu IP oraz portu nasłuchującego danego węzła. Identyfikatorem nowo przyłączonego węzła staje się jego własny IP oraz port nasłuchujący i pozwala on jednoznacznie identyfikowad użytkowników w sieci. Po podłączeniu do danego węzła następuję wymiana pomiędzy nimi komunikatów: 1. Wysyłamy do zdalnego węzła wiadomośd MyIP z naszym adresem i portem. 2. Odbieramy taką sama wiadomośd od podłączonego do nas węzła. 3. Przesyłamy aktualną historie wszystkich wiadomości, zarówno publicznych jak i prywatnych. 4. Przesyłamy mu listę statusów wszystkich komunikatorów w sieci. 5. Przesyłamy informację o backupie, zgodnie z przyjętymi zasadami. Odłączenie się węzła: W przypadku zakooczenia komunikatora w sposób standardowy lub awarii węzeł do którego był podłączony przesyła do wszystkich status offline z id użytkownika, który się odłączył. W wyniku odłączenia się jednego z węzłów, może dojśd do podziału sieci, dlatego wszystkie węzły, dla których odłączony węzeł pełnił rolę serwera podłączają się do węzła zdefiniowanego, jako backup (o ile jest to możliwe). Rozpowszechnianie komunikatów po sieci Komunikaty zdefiniowane wcześniej można podzielid na dwie kategorie: komunikatów broadcastowanych i point 2 point. Wiadomości broadcastowane są przesyłane do wszystkich innych użytkowników. Zalicza się do nich wiadomości message i status. Pozostałe wiadomości, czyli myip i backup są przesyłane wyłącznie do konkretnych węzłów i nie są przesyłane dalej.
Przesyłanie wiadomości Wiadomości dzielą się na dwa rodzaje: publiczne prywatne Wiadomości publiczne są adresowane do wszystkich użytkowników, i dany węzeł po ich odebraniu wyświetla je po czym przesyła je dalej. Wiadomości prywatne są adresowane wyłącznie do jednego użytkownika, wszystkie węzły, które napotka po drodze mają za zadanie jedynie je przekazad dalej. Czas wektorowy wiadomości Wiadomośd message jest przesyłana wraz z logicznym czasem wektorowym. Służy on do identyfikacji poszczególnych wiadomości i pozwala wykryd sytuacje, w której dana wiadomośd została otrzymana po raz drugi. Do obsługi czasu wektorowego definiuje się następujące operacje: W przypadku wysyłania, nadawca inkrementuje swój czas, nie zmieniając pozostałych, po czym wysyła wiadomośd. Przyjęto, że każdy proces inicjuje swój czas wartością 1. Pierwsza wysłana przez niego wiadomośd będzie, więc miała czas 2. W przypadku odebrania wiadomości łączymy wektor odebrany z wiadomości wraz z naszym, w przypadku elementów, które się nie powielają nie ulegają one zmianie i są dodawane do wynikowego wektora. W pozostałych wybierany jest maksymalny czas z obu wektorów: max(wektor_wiadomości, nasz_wektor). Gdy komunikator otrzymuje wiadomośd, pierwszą rzeczą, którą sprawdza to jej czas wektorowy nadawcy, wiadomośd jest przesyłana dalej tylko w wypadku, gdy czas wektorowy z wiadomości jest większy od tego zapisanego u odbiorcy. W przeciwnym wypadku wiadomośd nie jest przekazywana dalej. Synchronizacja wiadomości Nowo połączone węzły synchronizują historię wiadomości z innymi komunikatorami. Historię wiadomości otrzymuje się od węzła do którego się dany komunikator podłączył. Otrzymuje on historię wszystkich rozesłanych po sieci wiadomości uwzględniając w tym wiadomości prywatne i publiczne. Backup Każdy z sąsiadów ma przypisany swój węzeł Backup (o ile jest podłączony do przynajmniej 2 węzłów), jest to węzeł do którego należy się podłączyd w przypadku odejścia tego sąsiada.
Rys.1 Kolorowe strzałki to wskazują węzły, do których należy się połączyd w przypadku odejścia sąsiada o tym kolorze. Rys.2-4 Szary węzeł to sąsiad, który odszedł, kolorowe strzałki to nowe połączenia. Węzłem Backup jest w pierwszej kolejności nasz rodzic, jeśli nie mamy rodzica to jest to pierwsze z naszych dzieci (o ile mamy więcej niż 1 dziecko, w przeciwnym wypadku i tak nie mamy komu wysład tego węzła). Adres węzła backup jest aktualizowany i na nowo przesyłany przy: podłączeniu się kogoś do nas (wtedy my jesteśmy rodzicem tej osoby) odłączeniu się kogoś od nas podłączeniu się nas do kogoś (wtedy my jesteśmy dzieckiem tej osoby) Takie rozwiązanie posiada jedną wadę, powoduje, że sied rozpadnie się jeśli nie będziemy mieli możliwości połączenia do naszego węzła backup (czyli np padnie nasz rodzic oraz rodzic rodzica w tej samej chwili i w tym krótkim czasie nie zostanie wyznaczony nowy węzeł backup).