Synchronizacja czasu przez internet

0
adf88 napisał(a):

To ja dodam jeszcze, że timeout ustawiony na 1 sekundę to mało. Można odpalić kilka wątków, jeden na każdy serwer, timeout dać na jakieś 30 sekund, a gdy odpowie pierwszy serwer to ubić resztę wątków.

Powiem tak - nie jest mi potrzebny serwer, który odpowiada po kilku, czy nawet kilkunastu sekundach. Ja potrzebuję takiego, który odpowiada natychmiast. W czasie działania aplikacji niektóre czynności są zapisywanie w bazie danych z dokładną godziną co do sekundy. Zanim aplikacja tą czynność zapisze w bazie, pobiera więc aktualną godzinę z serwera (nie chcę, żeby pobierał z systemu, bo w Windowsie można ręcznie zmienić). Jeśli program miałby przy każdej takiej operacji się zastanawiać, uruchamiać ileś wątków trwających po 30 sekund, to raczej nie wpłynęło by to pozytywnie na jego szybkość działania. W 99% przypadków ten pierwszy serwer odpowie i nie będzie żadnego czekania. W pozostałych 1% przypadków odczeka sekundę i sprawdzi drugi serwer z listy i on będzie dostępny. Raz na tysiąc przypadków może się zdarzyć, że właśnie utraciło się połączenie z internetem i żaden serwer nie będzie dostępny. Zastanawiam się wręcz nad zmniejszeniem tego timeouta, bo mam to zaprogramowane tak, że program w przypadku udanej próby pobrania czasu "zapamiętuje" z którego serwera go pobrał i przy następnej okazji zaczyna pobieranie od niego. Dlatego jak jakiś serwer odpowiada np. dopiero po 900 ms, to chyba lepiej, jakby go program zignorował i poszukał innego, bo później co chwilę będzie robił niepotrzebne lagi w trakcie działania aplikacji.

0

W takim razie powinieneś zrobić to zupełnie inaczej. Czas pobrać raz i później tylko dodawać do niego ilość czasu jaka upłynęła od pobrania. Natomiast wystartowanie kilku wątków które by odpytywały serwery to żadne obciążenie dla aplikacji, a w ten sposób odpowiedź otrzymasz najszybciej.

0
adf88 napisał(a):

W takim razie powinieneś zrobić to zupełnie inaczej. Czas pobrać raz i później tylko dodawać do niego ilość czasu jaka upłynęła od pobrania.

A jak obliczysz czas, jaki upłynął od jego pobrania? Bo porównanie systemowego czasu z momentu pobrania z "obecnym" systemowym czasem też odpada, bo przecież w międzyczasie ktoś mógł zmienić godzinę w systemie.

0

No to już jest jego problem... ale na Windowsie możesz chyba użyć GetTickCount, zmiana systemowego czasu nie powinna wpływać na wyniki zwracane przez tą funkcję, a przynajmniej tak wynika z dokumentacji. Nie sprawdzałem jak to jest w praktyce.

0

No tak, ale czasu nie zatrzymasz - "tykać" będzie zawsze więc możesz po prostu zwiększać licznik w czasie działania programu o 1 co sekundę i porównywać z systemowym, choć to i tak jest dość ryzykowne bo istnieje możliwość rozsynchronizowania tych czasów np. stosując komponent timer do zliczania sekund. Idealnym rozwiązaniem jest architektura klient - serwer bo tam nikt w zegarku grzebać nie będzie. Można też sprawdzać czy ostatnia data w bazie przed dodaniem jest starsza od tej, którą chcesz dodać - jeśli nie to ktoś cofnął czas. Niestety to zadziała post factum i user dowie się dopiero jak cofnie czas.
Teraz zastanówmy się po co ci dokładny czas. Przy dodawaniu jakiegoś rekordu zwiększasz i tak ID co daje ci porządek chronologiczny. Jeśli bazy nie musisz scalać od klientów w jednym miejscu to nie ma to jakie ma znaczenie data? W innym przypadku trzeba postawić 1 serwer bazodanowy. Jeśli user sobie przestawi datę to szkodzi tylko sobie.

0

Np GetTickCount zwróci liczbę poprawną liczbę MS mimo zmiany czasu w systemie. Tak można obliczyć czas:

var
  MyTime: TDateTime;
  LastTimeMS: Cardinal;
begin
  MyTime:= Now;
  LastTimeMS:= GetTickCount;
  //tu cos do zrobienia miedzy pomiarami mozna robic
  ShowMessage(DateTimeToStr(MyTime + (GetTickCount - LastTimeMS) / MSecsPerSec / SecsPerDay));
end;
0
adf88 napisał(a):

No to już jest jego problem...

Nie, to nie jego problem tylko mój - programisty. W bazie ma być PRAWDZIWY czas, kiedy ktoś dokonał danej operacji, a nie że pracownik będzie sobie zmieniał datę systemową i tym samym naginał rzeczywistość.

Ten GetTickCount może być ciekawy, bo takie zwiększanie licznika w tle, to niezbyt fajne rozwiązanie. Jak będę miał czas, to się nad tym GetTickCount pochylę. Póki co to pobieranie dokładnego czasu z internetu funkcjonuje dobrze.

Jeden serwer bazodanowy? Tak mam. W sumie teraz o tym pomyślałem, że dokładny czas można by z niego też pobierać... Baza jest mysql. Chyba jakoś się da?

0

Fajnie, że dopiero teraz o tym wspominasz. Oczywiście MySQL ma funkcje do pobierania aktualnej daty i czasu, w którym dodawany jest faktycznie rekord np. NOW(), po więcej odsyłam do http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html

0

Baza jest na serwerze? No nie żartuj sobie, czemu tak istotnej informacji nie podałeś. Niech serwer liczy czas!!! Przecież to się samo od razu nasuwa.

0
adf88 napisał(a):

Baza jest na serwerze? No nie żartuj sobie, czemu tak istotnej informacji nie podałeś.

Myślałem, że to logiczne ;-)
Pisze ktoś jeszcze aplikacje jednostanowiskowe? ;-)
Jak znajdę czas, to pochyle się nad tym.

0
Ozi napisał(a):

Pisze ktoś jeszcze aplikacje jednostanowiskowe? ;-)

Nie, nikt nie pisze, a SQLite czy SQLServer Compact powstają bo programiści nie mają co robić :D

Zdziwiłbyś się jak wiele aplikacji chodzi na local DB.

0

Zwłaszcza, że od początku upierasz się, żeby pobierać czas z internetu. Ale tak to już niestety z niektórymi jest. Ludzie zamiast opisać swój problem opisują własne wyobrażenie jego rozwiązania a później się okazuje, że podejście jest zupełnie złe. A jak się ich pyta w czym mają problem, czy "po co ci to" to się dupą odwracają lub twierdzą, że to nieistotne.

0

Ojoj, nie wyolbrzymiajcie znowu :-) Nigdy nie odpisałem "po co ci to". Jakby mnie ktoś zapytał, to na pewno bym odpowiedział. Jak szopenfx zapytał mnie po co mi dokładny czas, to mu odpisałem, że potrzebuję zapisywać dokładną godzinę danej operacji wykonanej przez użytkownika aplikacji. Jakby mnie ktoś zapytał, czy ta aplikacja korzysta z bazy na innym komputerze (serwerze), to przecież bym odpowiedział, że tak. Po każdej waszej odpowiedzi dziękuję wam za pomoc. Dałem d**y, że nie kapnąłem się od razu, że można by pobierać czas z mojego serwera mysql i jeśli kogoś tym wku**iłem, to przepraszam. Myślę jednak, że potomnym ta nasza rozkminka i tak się przyda, bo prędzej czy później znajdzie się ktoś, kto będzie robił aplikację jednostanowiskową i będzie potrzebował godziny niezależnej od tej w swoim komputerze. Wyluzujcie, piątek jest :-)

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