Mam kilka problemów z pisanym przeze mnie oprogramowaniem:
Napisałem aplikację, która umożliwia zdalne zarządzanie wieloma komputerami. Apka działa poprawnie jeżeli jest uruchomiona z prawami administratora (choć i nad tym pracuję). Docelowo wszystko będzie działać w tle, ale na potrzeby testów muszę mieć jakiś wyraźny feedback by sprawdzić czy wszystko działa poprawnie.
Docelowo każdy klient (inny komputer) łączy się z serwerem (aktualnie bezpośrednio z moim komputerem, choć w późniejszej wersji oprogramowania łączenie będzie pośrednie) na którym postawiłem prymitywną bazę danych opartą na plikach *.ini, gdzie pliki *.ini są parsowane przez moją "bibliotekę" bo ta windowsowa nawala (rozwiązanie tymczasowe, samą bazę danych planuję postawić na serwerze mysql).
No i tu zaczyna się problem z przesyłem danych, identyfikowaniem klienta i ogólnie zarządzaniem połączeniami.
Zrobiłem pulę wątków, gdzie główny wątek serwera rozdziela obsługę połączeń pomiędzy wolnymi wątkami. Problem w tym, że pula wątków jest statyczna i serwer jednocześnie może obsłużyć dajmy na to 10 połączeń. A przewiduję możliwość jednoczesnej obsługi mniej więcej 100 połączeń. I tu jest problem bo jednoczesne utrzymywanie około 100 wątków i jednoczesne blokowanie dostępu do bazy danych przy pomocy muteksów jest mocno nie wydajne.. (a czuję sie niepewnie stosując operacje atomowe)
No i dalej... jak rozwiązać identyfikację klientów? Na początku myślałem by identyfikować klientów po numerze IP, ale to bez sensu bo IP jest dynamiczne. Więc wpadłem na pomysł by przy pierwszym połączeniu klienta ten wysyłał "prośbę" nadania unikalnego ID przez serwer. Gdzie potem każde nowe połączenie klienta z serwerem będzie identyfikowane przy pomocy tego ID. Wydaje mi się to dobre rozwiązanie...
Jedną z podstawowych funkcji serwera jest utrzymywanie listy aktualnie połączonych klientów.. Jak to zrobić? Osobiście myślałem nad tym by co jakiś określony czas (dajmy na to 5 sekund) apka wysyłała swoje ID do serwera by powiadomić serwer o aktywnym połączeniu. Czy to jest wydajne? No bo to jest znowu około 100 aktywnych wątków aktywujących się co 5 sekund by obsłużyć proste polecenie.
Problem odzyskiwania serwera.
Problem jest w sytuacji gdy np u mnie w domu zabraknie prądu (bądź nastąpi jakakolwiek awaria czy restart komputera) to operator przydziela mi nowe IP. Nie mam łącza statycznego bo jest drogie, a na bieżącym etapie tego projektu jest to po prostu nieopłacalne.
I jeżeli operator przydzieli mi nowe IP, to klient nie będzie wiedział z kim ma się łączyć i całą bazę nieodwracalnie szlag trafi.
Jak to zrobić?
Osobiście myślałem by w razie gdy klient nie mógłby się połączyć z serwerem to by nie tracić danych, zrobił dumpa z danymi na jakiś ogólnodostępny serwer (dane oczywiście szyfrowane) i w momencie naprawienia awarii serwer mógł jest jakoś odzyskać i przekierować ruch już normalnie.
Ale to jest na razie mocno koncepcyjne rozwiązanie i konstrukcyjnie nie wiedziałbym jak to rozwiązać.
Jest jeszcze kilka innych kwestii do rozwiązania, jak np. planuję zrobić by serwer był mobilny, tzn abym mógł sterować oprogramowaniem z różnych urządzeń i tu też jest problem z identyfikacją numeru serwera.
Możnaby to też rozwiązać w ten sposób, że musi być aktywny jeden serwer a administrator z dowolnego urządzenia steruje serwerem zdalnie (serwer musi mieć statyczne łącze). Albo rozwiązanie mniej mniej elastyczne, ponieważ mógłbym dać klientom sztywną listę serwerów z którymi mogłyby się łączyć, ale to i tak zawsze musiałby być aktywny przynajmniej jeden serwer...
Jako biblioteki sieciowej używam boost::asio (mam nadzieję, że pewnego dnia trafi ona do standardu).
Jeżeli macie jakieś sugestie jak to zoptymalizować czy macie nawet lepsze rozwiązania to śmiało pisać.
Pozdrawiam.