Created
March 31, 2014 23:16
-
-
Save anonymous/9904508 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Эта приблуда - клиент, который получает время с удаленной машины | |
# Смотреть будем на миллисекунды | |
require 'net/http' | |
measures = [] | |
roundtrips = [] | |
uri = URI.parse "http://сервервремени:2000" | |
# Спецификация NTP какбэ рекомендует спрашивать время несколько раз, минимум 8. | |
8.times do | |
local_time = Time.now.utc.to_f * 1000 # время до выполнения запроса | |
remote_time = Net::HTTP.get_response(uri).body.to_f # результат с сервера времени | |
now_time = Time.now.utc.to_f * 1000 # время после обработки запроса | |
measures << ((remote_time - local_time) + (remote_time - now_time))/2 # вычисление оффсета (смотри NTP БЛЕА) | |
roundtrips << (now_time - local_time) # время путешествия пакетов | |
p "before request: #{local_time}" | |
p "remote time: #{remote_time}" | |
p "now: #{now_time}" | |
p "req time: #{now_time-local_time}" | |
p "Remote-req: #{remote_time - local_time}" | |
p "req-now: #{now_time - remote_time}" | |
p "offset: #{measures.last}" | |
p "trip: #{roundtrips.last}" | |
p "-----" | |
end | |
# А теперь в чистовом варианте с применением усредненного оффсета и половины времени прохождения пакетов | |
local_time = Time.now.utc.to_f * 1000 # время до выполнения запроса | |
remote_time = Net::HTTP.get_response(uri).body.to_f # результат с сервера времени | |
now_time = Time.now.utc.to_f * 1000 # время после обработки запроса | |
avg_offset = measures[1..-1].reduce(:+).to_f / measures.size # среднее арифметическое от оффсета | |
avg_trip = roundtrips[1..-1].reduce(:+).to_f / roundtrips.size # среднее арифметическое от времени пути | |
p "Now - remote time: #{now_time - remote_time}" | |
p "Now - corrected time: #{now_time - (remote_time + avg_offset + (avg_trip/2)) }" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# очень простой сервер времени | |
require 'webrick' | |
server = WEBrick::HTTPServer.new :Port => 2000 | |
server.mount_proc "/" do |req, res| | |
res.body = (Time.now.utc.to_f * 1000).to_s | |
end | |
trap('INT') { server.stop } | |
server.start |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Пробуем на локальном сервере | |
"Now - remote time: 0.119873046875" | |
"Now - corrected time: 0.00341796875" | |
Пробуем на удаленном (время с локальным синхронизировано через ntp) | |
"Now - remote time: 198.780029296875" | |
"Now - corrected time: 37.198974609375" | |
Вывод: | |
С помошью нехитрых вычислений, уровень погрешности при получении времени с сервера понизился в несколько раз. Все, что сделано - это по сути отфильтрована сетевая задержка. Так как клиент-сервер написаны на руби, то они сами по себе нещадно глючат. | |
В любом случае, это всего-лишь показывает, что передача времени в чистом виде через HTTP-запрос без фильтрации врет как собака. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment