Witam, nie dawno rozpocząłem tworzenie projektu gry mmorpg wraz z niewielkim czteroosobowym zespołem. W zespole zajmuje się tworzeniem serwera gry. Client gry powstaje w unity, gdzie cały networking będzie tworzony przy użyciu C#. Serwer postanowiłem napisać w C++ przy użyciu biblioteki boost.asio. Pomimo, że napisałem już jakiś podstawowy kod, wciąż mam problem w przemyśleniu dobrej architektury serwera. Głównym problemem jest to jak ma przebiegać komunikacja server-client. Rozpisałem kilka możliwych schematów takiej komunikacji, jednak jako iż wcześniej miałem mało do czynienia z networkingiem, nie wiem który schemat będzie dobry do wymagań projektu.
Z początków moich prac nad serwerem miałem w głowie tylko jeden schemat. Na obrazku z komunikacją jest to schemat 3. Tzn. mamy klienta, który łączy się z jednym serwerem. Ten serwer robi wszystko począwszy od autoryzacji użytkowników, aktualizowania stanu gry, przy tym wysyłając odpowiednie zapytania do serwera bazy danych. Jednak wraz z biegiem czasu pomyślałem, że dobrym wyjściem byłoby rozdzielić ten jeden serwer na kilka podrzędnych, które działały by na różnych wątkach, lub w ogóle jako osobne procesy.
Dwa z nich to serwer gry oraz serwer autoryzacyjny. W celu rejestracji/logowania przez użytkownika, wysyłałby on odpowiedni pakiet na serwer autoryzacyjny, który zwracał by token uwierzytelnienia. W ten sposób klient mógłby się już łączyć z serwerem gry.
Aby uniknąć potrzeby bezpośredniego łączenia z serwerem bazy danych przez te dwa serwery, pomyślałem jeszcze czy by nie zrobić trzeciego serwera - takiego connectora do serwera bazy danych. Ten serwer byłby odpowiedzialny za łączność z bazą danych przez konstruowanie odpowiednich zapytań. Serwer ten komunikowałby się wyłącznie z serwerem autoryzacyjnym oraz serwerem gry, tzn. bezpośredni dostęp do tego serwera przez klienta nie byłby możliwy. A więc w przypadku tego serwera następowałaby komunikacja server-server.
I z tym serwerem mam duży dylemat, bo myślę, że taka komunikacja mogła by trochę wprowadzać bałagan w projekcie.
Jeśli chodzi o moje pojęcie tych serwerów, to mam na myśli serwer udp bądź serwer tcp przy użyciu biblioteki asio. W moim zamyśle serwer autoryzacyjny powinien być zrealizowany z użyciem protokołu tcp, a z serwerem gry następuję mały kłopot, gdyż wolałbym wykorzytać tych dwóch protokołów. Protokołu udp użyłbym w celu przesyłania danych, których utrata nie będzie miała dużego znaczenia, np. pakiet danych poruszającego się gracza. Jednak ta myśl znowu trochę utrudni sprawę, więc raczej zdecydowałbym się na robienie wszystkiego na protokołach tcp.
Czy mój tok rozumowania działania takiej architektury jest sensowny? Moim celem byłoby stworzenie serwera, który obsługiwałby ponad 1000 graczy jednocześnie, jednak nie wiem czy taka architektura nie skomplikuje zbytnio tego procesu. Wiadomo, że dużo zależy od tego jak to zaprogramuje, jednak nie chciałbym się w połowie tworzenia zorientować, że to co zrobiłem, przemyślałem było złe i przebudowywać wszystko inaczej.
Serwer ten piszę w środowisku Visual Studio, gdzie całe rozwiązanie podzieliłem na podrzędne projekty. Każdy z serwerów ma swój odpowiedni projekt. Mam także stworzony projekt "NetworkCore", który dostarcza potrzebne funkcje do innych projektów. W NetworkCore chcę skupić się na elementach, które będą kluczowę do działania tych podrzędnych projektów. Póki co zaimplementowałem w nim klasy serwera UDP oraz TCP, klasę pakietu, klasę do serializacji pakietów, klasę, która umożliwia połączenie. A w przyszłości będzie tego o wiele więcej.
Poniżej przedstawiam schematy, które zrobiłem do tej pory. Możliwe jest, że coś w nich napisałem nie do końca jasno albo narysowałem mało poprawnie, ale myślę, że będzie widać o co mi chodzi. Będe wdzięczny za jakieś wskazówki, który z tych typów komunikacji oznaczonych odpowiednio na obrazku, będzie dobrym rozwiązaniem. Mam świadomość, że każda z tych komunikacji może byłaby odpowiednia, ale to dużo zależy od innych czynników, a więc głównie chciałbym się dowiedzieć jakie są wady i zalety rozwiązania z podziałem komunikacji na kilka serwerów. Słyszałem coś ostatnio o architekturze mikroserwisów. Czy taka architektura byłaby w tym przypadku rozsądna i jak bardzo bym mógł jeszcze to rozbudować?
Dziękuje :)
Moje trzy pomysły: