Architektura serwera

0

Cześć,
chce napisać prosty serwer ale zastanawiam się jak rozwiązać jedną kwestię. Do serwera będą podłączać się klienci, wysyłać prośby o różne informacje a serwer będzie je odsyłać.
Wymyśliłem 2 rozwiązania:

  • dla każdego Klienta odpalę osobny wątek, gdzie będę odbierać od niego informacje i odsyłać dane,
  • stworzę kolejkę informacji przychodzących do serwera a następnie je parsować, zwracać dane i odsyłać do nadawcy (których będę trzymać w jakieś mapie czy tablicy).

Oba te rozwiązania są do zrobienia (szczerze to już nawet kiedyś je zaimplementowałem) ale cały czas mam co do nich wątpliwości. Gdyby na tym miało się skończyć to nie ma problemu. Jednak czasami klient A chce wysłać wiadomość do klienta B.
Jak w takiej sytuacji rozwiązać problem przekazywania danych od A do B?

Mogę odbierać dane od klientów w wątkach ale odpowiedzi wrzucać do jakiegoś zbiorczego bufora gdzie jednym wątkiem będę rozsyłać informacje do odbiorców?

Jak to rozwiązać żeby było najbardziej optymalne i eleganckie? Jak to się robi w "poważnych" aplikacjach?
Bardzo proszę o pomoc.

Dzięki! :)

3

http://www.aosabook.org/en/nginx.html
Rozważ używanie puli wątków i selecta (epoll jeżeli robisz to niskopoziomowo na linuxie) zamiast wątku per klient. Generalnie wątki są wygodne, ale mają swoje narzuty i w wysoko wydajnych aplikacjach na "ścieżce danych" (data plane) raczej się z nimi nie przegina (chyba, że mowa o wątkach poziomu użytkownika i to z małym stosem, na przykład goroutines w golang, wtedy można spokojnie tworzyć ich dużo więcej).

Kluczowe pytanie to czy wiadomość od klienta A do B ma iść na otwartym już połączeniu? Jeżeli tak to wiadomości pomiędzy klientami proponowałbym zapisywać w kolejce w pamięci (per klient) Jeżeli zakolejkowane a nie wysłane wiadomości mają przetrwać restart serwera zrzucać to do bazy (klucz-wartosc wystarczy), ewentualnie samemu na dysk, ale pisanie append-loga to już sporo zabawy. Możesz też użyć gotowej kolejki komunikatów oferującej wzorzec publish-subscribe.
Wątek obsługujący klienta musiałby raz na jakiś czas zczytywać informacje ze swojej kolejki i je rozsyłać.

Ewentualnie jeszcze bardziej to podzielić, tj na kolejki zadań. Połączenia przychodzące po zaakceptowaniu byłyby kolejkowane jako zadania (zadanie odczytania wiadomości od klienta). Pula watków robotników wykonywałaby te zadania. W przypadku konieczności przekazania wiadomości do innego klienta kolejowane byłoby nowe zadanie (zadanie wysłania wiadomości do klienta). Musiałbyś jedynie zadbać, by wiadomości odczytu od klienta A i wysłania do klienta A trafiały do tego samego wątku, albo przynajmniej nie były jednocześnie obsługiwane w różnych wątkach, by nie synchronizować się nadmiarowo.

Tyle koncepcyjnie, może ktoś jeszcze zaproponuje gotowe biblioteki. Jaki język wybrałeś?

1 użytkowników online, w tym zalogowanych: 0, gości: 1