Как сохранить синхронизацию между сервером и клиентом для точных сетевых игр, таких как Quake 3
Как сохранить синхронизацию между сервером и клиентом для точных сетевых игр, таких как Quake 3?
Я работаю над 2D-шутером сверху вниз и стараюсь копировать концепции, используемые в сетевых играх, таких как Quake 3.
- У меня есть авторитетный сервер.
- Сервер отправляет снимки клиентам.
- Снимки содержат метку времени и позиции объекта.
- Объекты интерполируются между положениями снимка, поэтому движение выглядит плавным.
- По необходимости, интерполяция сущностей происходит немного «в прошлом», поэтому у нас есть несколько снимков, между которыми можно интерполировать.
Проблема, с которой я сталкиваюсь, это «синхронизация часов».
- Для простоты давайте на мгновение представим, что при передаче пакетов на сервер и с него существует нулевая задержка.
- Если часы сервера на 60 секунд опережают часы клиента, то метка времени снимка будет на 60000 мс впереди локальной метки времени клиента.
- Следовательно, моментальные снимки сущности будут собираться и храниться в течение примерно 60 секунд, прежде чем клиент увидит, что какой-то конкретный объект делает свои ходы, потому что это занимает много времени, чтобы часы клиента успели догнать.
Мне удалось преодолеть это путем вычисления разницы между часами сервера и клиента при каждом получении снимка.
При определении того, как далеко находится объект интерполяции, я просто добавляю разницу к текущему времени клиента. Проблема с этим, однако, заключается в том, что это вызовет дрожание, потому что разница между двумя часами будет резко колебаться из-за того, что моментальные снимки поступают быстрее / медленнее, чем другие.
Как я могу синхронизировать часы достаточно близко, чтобы единственной ощутимой задержкой была та, которая жестко запрограммирована для интерполяции, и та, которая вызвана обычной задержкой в сети?
Другими словами, как я могу предотвратить слишком позднюю или слишком раннюю интерполяцию, когда часы значительно десинхронизированы, без появления рывков?
Редактировать: Согласно Википедии , NTP может использоваться для синхронизации часов через Интернет с точностью до нескольких миллисекунд. Тем не менее, протокол кажется сложным, и, возможно, излишним для использования в играх?
После поисков, кажется, что синхронизация часов двух или более компьютеров не является тривиальной задачей. Протокол, подобный NTP, хорошо работает, но он, предположительно, медленный и слишком сложный, чтобы быть практичным в играх. Кроме того, он использует UDP, который не будет работать для меня, потому что я работаю с веб-сокетами, которые не поддерживают UDP.
Я нашел способ здесь , однако, что , кажется , относительно проста:
Он утверждает, что синхронизирует часы с точностью до 150 мс (или лучше) друг от друга.
Я не знаю, будет ли это достаточно хорошо для моих целей, но я не смог найти более точную альтернативу.
Вот алгоритм, который это обеспечивает:
- Клиент маркирует текущее местное время в пакете «запрос времени» и отправляет на сервер
- При получении сервером сервер помечает серверное время и возвращает
- После получения клиентом клиент вычитает текущее время из отправленного времени и делит на два для вычисления задержки. Он вычитает текущее время из времени сервера, чтобы определить дельту времени клиент-сервер, и добавляет половину задержки, чтобы получить правильную дельту часов. (Пока этот algothim очень похож на SNTP)
- Первый результат должен быть немедленно использован для обновления часов, поскольку он доставит локальные часы по крайней мере в правую точку (по крайней мере, в правильный часовой пояс!)
- Клиент повторяет шаги с 1 по 3 пять или более раз, каждый раз останавливаясь на несколько секунд. В промежутке может быть разрешен другой трафик, но для достижения наилучших результатов его следует минимизировать.
- Результаты приема пакетов накапливаются и сортируются в порядке наименьшей задержки на наибольшую задержку. Медианная задержка определяется путем выбора выборки средней точки из этого упорядоченного списка.
- Все образцы выше приблизительно 1 стандартного отклонения от медианы отбрасываются, а остальные образцы усредняются с использованием среднего арифметического.
Это решение, кажется, удовлетворительно отвечает на мой вопрос, потому что оно синхронизирует часы и затем останавливается, позволяя времени течь линейно. В то время как мой первоначальный метод постоянно обновлял часы, заставляя время немного подскочить при получении снимков.
По сути, вы не можете исправить [весь] мир и, в конце концов, вам придется провести черту.
Если сервер и все клиенты имеют одинаковую частоту кадров, им просто нужно синхронизироваться при подключении, а иногда и после него, особенно после события задержки. Задержка не влияет на течение времени или способность ПК измерять его, поэтому во многих случаях вместо интерполяции необходимо экстраполировать. Это создает одинаково нежелательные эффекты, но, опять же, это то, что есть, и вы должны выбрать наименьшее из всех доступных зол.
Учтите, что во многих популярных MMO отстающие игроки визуально очевидны. Если вы видите, что они бегут на месте, прямо в стену, ваш клиент экстраполирует. Когда ваш клиент получит новые данные, игрок (на его клиенте), возможно, переместился на значительное расстояние и будет «резиновым» или телепортироваться в новое место («джерки», о котором вы упоминали?). Это происходит даже в крупных играх известных брендов.
Технически, это проблема сетевой инфраструктуры игрока, а не вашей игры. Точка, в которой он переходит от одного к другому, — это та самая линия, которую вы должны нарисовать. Ваш код на 3 отдельных компьютерах должен более или менее записывать одинаковое количество прошедшего времени. Если вы не получаете обновление, оно не должно влиять на частоту кадров вашей Update (); во всяком случае, это должно быть быстрее, так как, вероятно, меньше обновлений.
«Если у вас плохой интернет, вы не можете играть в эту игру на конкурентной основе».
Это не попутный доллар или ошибка.
7.15 ntpdate — утилита синхронизации времени в ОС
В РЕД ОС синхронизировать время можно следующими основными способами:
- вручную при помощи утилиты ntpdate;
- автоматически при помощи сервиса ntp.
Программа ntpdate — позволяет разово синхронизировать локальное время с эталонным сервером времени в интернете. Подобных эталонов существует достаточно много. Для примера можно воспользоваться одним из них — pool.ntp.org.
Запускаем синхронизацию времени:
Утилита провела синхронизацию, в результате которой к системному времени было добавлено число секунд, необходимое для приближения к эталонному. Если в результате работы синхронизации возникает ошибка: «no server suitable for synchronization found», то попробуйте в работе утилиты использовать непривилегированный порт. По-умолчанию ntpdate работает по 123 порту. Если он закрыт на фаерволе, то помочь в синхронизации поможет следующий параметр:
Если у вас запуск ntpdate завершается ошибкой — «the NTP socket is in use, exiting», значит у вас уже установлена и запущена служба ntpd, которая заняла необходимый udp-порт, необходимый для работы ntpdate.
Сервер времени ntp использует в своей работе одноименный протокол — Network Time Protocol, которому для работы необходим UDP-порт 123. Так что перед установкой и настройкой службы времени убедитесь, что на фаерволе открыт этот порт.
Устанавливаем сервер ntp:
Если вы используете РЕД ОС версии 7.1 или 7.2, выполните команду:
Если вы используете РЕД ОС версии 7.3 и старше, выполните команду:
Теперь отредактируем файл конфигурации /etc/ntp.conf, удалив все лишнее:
server | Список серверов для синхронизации времени. |
Driftfile | Задает адрес файла, в котором хранится история изменений времени во время синхронизации. Если по каким-то причинам синхронизация времени с внешними источниками станет невозможна, служба времени изменит системные часы в соответствии с записями в этом файле. |
Restrict 127.0.0.1 | Указывает, что пользоваться нашим сервером времени можно только непосредственно с локального интерфейса. Если вам необходимо разрешить другим компьютерам в вашей локальной сети синхронизировать время с текущей машины, то укажите в данном параметре адрес вашей сети, например: |
restrict 192.168.10.0 mask 255.255.255.0
restrict default nomodify notrap nopeer noquery — Параметры указывают на то, что клиентам данного сервиса времени запрещено изменять его настройки, получать его статус. Они могут только забрать с него значения точного времени.
disable monitor — Данный параметр повышает безопасность, предотвращая использования одной из уязвимостей сервиса ntpd, которую можно использовать для проведения DDoS атак.
Logfile — Указывает путь к файлу с логами сервиса.
После завершения редактирования файла настроек запускаем службу синхронизации времени:
Проверяем запустился ли сервер:
Все в порядке, служба слушает положенный порт 123. Проверим на всякий случай системные логи используемой ОС:
Теперь настроим автозапуск ntp вместе с загрузкой используемой ОС:
Наблюдать за работой службы ntp можно с помощью команды:
remote | Адрес удаленного эталона времени, с которого была синхронизация. |
Refid | Указывает, откуда каждый эталон получает точное время. Это могут быть другие сервера времени, система GPS и другое. |
St | Уровень (Stratum) это число от 1 до 16, которое указывает на точность эталона. 1- максимальная точность, 16 — сервер недоступен. Уровень вашего сервера будет равен уровню наименее точного удаленного эталона плюс 1. |
poll | Интервал в секундах между опросами. |
Reach | Восьмеричное представление массива из 8 бит, отражающего результаты последних восьми попыток соединения с эталоном. Бит выставлен, если удаленный сервер ответил. |
Delay | Время задержки ответа на запрос о точном времени. |
Offset | Разница между вашим и удаленным сервером |
jitter | Дисперсия (Jitter) — это мера статистических отклонений от значения смещения (поле offset) по нескольким успешным парам запрос-ответ. Чем меньше значение дисперсии, тем лучше, поскольку позволяет точнее синхронизировать время. |
Если вы нашли ошибку, пожалуйста, выделите текст и нажмите Ctrl+Enter.
Настройка NTP на сервере
В операционных системах существует немало служб, нормальное функционирование которых зависит от точности хода системных часов. Если на сервере не установлено точное время, это может стать причиной различных проблем.
Например, в локальной сети требуется, чтобы часы машин, совместно использующих файлы, были синхронизированы — иначе невозможно будет правильно устанавливать время модификации файлов. Это, в свою очередь может стать причиной конфликта версий или перезаписи важных данных.
Если на сервере не установлено точное время, возникнут проблемы с заданиями Cron — неясно, когда они будут запускаться. Будет очень трудно анализировать журналы системных событий для диагостики причин сбоев и неисправностей…
Продолжать можно долго…
Чтобы избежать всех описанных проблем, необходимо настроить синхронизацию системных часов. В Linux для этого используется протокол NTP (Network Time Protocol). В этой статье мы подробно расскажем о том, как на сервере осуществить установку и настройку NTP. Начнем с небольшого теоретического введения.
Как работает протокол NTP
В основе протокола NTP лежит иерархическая структура серверов точного времени, в которой выделяются различные уровни (англ. strata). К уровню 0 относятся эталонные часы (атомные часы или часы GPS). На нулевом уровне NTP-серверы не работают.
С эталонными часами синхронизируются NTP-серверы первого уровня, которые являются источниками для серверов уровня 2. Серверы уровня 2 синхронизируются с серверами уровня 1, но могут также синхронизироваться и между собой. Аналогичным образом работают серверы уровня 3 и ниже. Всего поддерживается до 256 уровней.
Иерархическая структура протокола NTP характеризуется отказоустойчивостью и избыточностью. В случае отказов соединения с вышестоящими серверами резервные серверы берут процесс синхронизации на себя. За счет избыточности обеспечивается постоянная доступность NTP-серверов. Синхронизируясь с несколькими серверами, NTP использует данные всех источников, чтобы рассчитать наиболее точное время.
Установка и настройка NTP-сервера
Самым известным и распространенным программным средством для синхронизации времени является демон ntpd. В зависимости от настроек, указанных в конфигурационном файле (об этом еще пойдет речь ниже), он может выступать как в качестве сервера, так и в качестве клиента (т.е может как принимать время с удаленных хостов, так и раздавать его другим хостам). Ниже мы подробно расскажем о том, как осуществляется установка и настройка этого демона в OC Ubuntu.
Установка
Программа NTP входит в состав дистрибутивов большинства современных Linux-систем и устанавливается при помощи стандартного менеджера пакетов:
Настройка
По завершении установки откроем в текстовом редакторе файл /etc/ntp.conf. В нем хранятся все настройки программы. Рассмотрим их более подробно.
Параметры логирования
Первая строка конфигурационного файла выглядит так:
В ней указывается файл для хранения информации о частоте смещения времени. В этом файле хранится значение, получаемое в результате предшествующих корректировок времени. Если внешние NTP-серверы по той или иной причине становятся недоступными, значение будет взятого из него.
Далее указывается файл, в который будут сохраняться логи синхронизации:
Список серверов для синхронизации
В конфигурационном файле указывается список NTP-серверов, с которыми будет осуществляться синхронизация. По умолчанию он выглядит так:
Каждая строка означает группу серверов, которые будут cообщать нашему серверу корректное время. Повысить точность синхронизации можно с помощью опции iburst (она указывает, что на сервер для синхронизации нужно посылать не один, а несколько пакетов):
Можно также указать предпочитаемый сервер при помощи опции prefer:
NTP-серверы разбросаны по всему миру (вот, например, список доступных публичных NTP-серверов ). Чтобы обеспечить более точную установку системных часов, рекомендуется синхронизироваться только с ntp-серверами того региона, в котором географически расположен наш сервер. Для этого в конфигурационном файле /etc/ntp.conf нужно указать в адресах серверов региональный поддомен для pool.ntp.org:
- Азия — asia.pool.ntp.org;
- Европа — europe.pool.ntp org;
- Африка — africa.pool.ntp.org;
- Северная Америка — north-america.pool.ntp.org;
- Южная Америка — south-america.pool.ntp.org;
- Океания — oceania.pool.ntp.org.
Можно также указывать поддомены для отдельных стран (подробнее см. здесь ). Имеется свой поддомен и для России — ru.pool.ntp.org
Резервный сервер точного времени
NTP-сервер, по какой-либо причине отключенный от Интернета, может передавать для синхронизации данные своих системных часов. Для этого в конфигурационный файл нужно добавить следующую строку:
Ограничения
В последнее время участились случаи использования NTP-серверов для усиления трафика в DDoS-атаках (подробнее об этом см., например, здесь ). Чтобы наш сервер не стал жертвой злоупотреблений, нелишним будет установить ограничения на доступ для внешних клиентов. По умолчанию в файлe /etc/ntp.conf установлены следующие ограничения:
Параметры nomodify, notrap, nopeer и noquery запрещают сторонним клиентам изменять что-либо на сервере. Параметр kod (эта аббревиатура означает kiss of death — «поцелуй смерти») обеспечивает дополнительную защиту: клиент, отправляющий слишком частые запросы, сначала получит так называемый kod-пакет (предупреждение об отказе в обслуживании), а затем будет отключен от сервера.
Чтобы с NTP-сервером могли синхронизироваться машины из локальной сети, добавим в конфигурационный файл следующую строку:
Для локального хоста можно установить доступ к NTP-серверу без ограничений:
Проверка синхронизации
После того, как все необходимые изменения внесены в конфигурационный файл и сохранены, перезапустим NTP-сервер:
Затем выполним следующую команду:
Ее вывод будет представлен в виде таблицы:
В таблице указываются следующие параметры:
- remote — адрес сервера точного времени (в этой графе отображаются серверы из списка в конфигурационном файле);
- refid — вышестоящий сервер (тот, от которого сервер из предыдушей графы получает синхронизацию);
- st — уровень (stratum) сервера;
- t — тип пира (u- unicast, m- multicast);
- when — время последней синхронизации;
- poll — время в секундах, за которое демон NTP синхронизируется с пиром;
- reach — состояние доступности сервера; после восьми успешных попыток синхронизации значение этого параметра становится равным 377;
- delay — время задержки ответа от сервера;
- offset — разница времени между нашим сервером и сервером синхронизации; положительное значение этого параметра означает, что наши часы спешат, отрицательное — что отстают;
- jitter — смещение времени на удаленном сервере.
Слева от адреса сервера могут быть указаны следующие символы:
- * сервер выбран для синхронизации;
- + сервер, пригодный для обновления (с которым можно синхронизироваться);
- — с сервером синхронизироваться не рекомендуется;
- х сервер недоступен.
Проверить, пригоден ли сервер из списка для синхронизации, можно при помощи команды:
Из приведенного вывода видно, что сервер пригоден для синхронизации, его уровень — 2, смещение — 0,127936 мс, задержка — 0.026 мс.
О том, как проходила синхронизация (успешно или с ошибками) можно также узнать из логов:
Установка локальной даты и времени
С помощью команды ntpdate можно установить на сервере локальную дату и время, отправив соответствующий запрос к NTP-серверу:
Невозможно синхронизировать время с сервером Ростелеком: куда ушел Харон?
Пользователи Интернета часто жалуются на появление ошибки «Невозможно синхронизировать время с сервером Ростелеком». Как правило, сообщение появляется при просмотре телевидения Wink. Ниже рассмотрим, в чем особенности этой технологии, по каким причинам происходит ошибка, и что делать при ее появлении.
Причины
Чтобы понять причины, почему в системе невозможно синхронизировать время с сервером Ростелеком Wink, нужно понимать особенности работы технологии. При определении времени применяется много систем, но наиболее популярная — NTP (иногда DHCP). С ее помощью удается получить данные о точном времени при помощи локальной сети и без применения сложных настроек.
С применением NTP удается синхронизировать временные параметры через глобальную сеть. При этом сам процесс подразумевает несколько этапов. Сначала оборудование пользователя Ростелеком запрашивает данные, а после применяет полученные сведения на своей аппаратуре.
Почему же тогда возникает ошибка, что невозможно синхронизировать время с сервером Wink.
Причина в том, что существует несколько уровней NTP-серверов:
- первого уровня — подключается напрямую к атомным часам и гарантируют высокую точность;
- второго и третьего уровня — работает с подключением с NTP-серверу первого уровня, поэтому высок риск погрешности.
Оборудование клиентов Ростелеком должно компенсировать возникающие задержки. Специальные сервисы контролируют точность информации и корректирует сведения при необходимости. Если появляется ошибка «Невозможно синхронизировать время с сервером», это свидетельствует о сбоях в настройке оборудования или какой-то неисправности.
Что делать
Для устранения ошибки может потребоваться несколько действий. Рассмотрим наиболее важные шаги.
Перезагрузите оборудование
Если появляется надпись, что невозможно синхронизировать временные параметры с сервером Ростелеком, перезапустите устройства. Для начала перезагрузите приставку, а потом и само приложение. Как правило, эти действия позволяю вернуть работоспособность оборудованию и синхронизироваться с правильными данными на часах.
Задайте правильные данные
Как вариант, попробуйте синхронизировать временные параметры с сервером. Алгоритм такой:
- запустите на межсетевом экране стандартный порт NTP и установите разрешение на входящие/исходящие соединения;
- определите действующий ПДС-сервер путем записи в строке ввода команд C:>netdom /query fsmo;
- остановите работу службы Виндовс Тайм — введите команду C:>net stop w32time;
- настройте внешний временной источник, для чего введите C:> w32tm /config /syncfrom _(источник)_);
- активируйте доступ к домену — введите C:>w32tm /config /reliable:yes;
- запустите службу Виндовс Тайм — C:>net start w32time.
После выполнения указанных действий временная служба должна синхронизировать информацию с внешним источником. Для получения подробных сведений необходимо ввести в командной строке следующий набор символов — C:>w32tm /query /configuration.
Проверьте настройки приставки
Ошибка с надписью, что невозможно синхронизировать время с сервером Ростелеком, может появиться из-за отсутствия информации. Как правило, оборудование получает сведения от NTP или DHCP серверов. Если приставка ТВ Ростелеком подключена через маршрутизатор или не получает данные от DHCP, в настройках времени и даты необходимо прописать вместо «авто» работающий сервер. Для этого сделайте следующее:
- войдите в меню приставки Ростелеком и Настройки;
- выберите пункт Дата и время;
- впишите в поле Сервер времени любой из адресов, к примеру, time.windows.com или какой-то из следующих вариантов (ntp21.vniiftri.ru и ntp.mobatime.ru);
- посмотрите, какое время отобразилось справа вверху.
Учтите, что в случае сброса ТВ-приставки данные NTP-сервера также обнулятся и придется выставлять все параметры заново.
Обратитесь за помощью
Если после указанных шагов все равно появляется ошибка, что невозможно синхронизировать время с сервером Ростелеком, свяжитесь с оператором. Для этого наберите телефон горячей линии ( 8-800-510-51-08 ) или напишите на электронную почту (wink@rt.ru). Объясните специалистам провайдера суть проблемы и попросите помочь с поиском решения.
Итоги
На практике надпись, что невозможно синхронизировать время с сервером Ростелеком, появляется в редких случаях. Если такая проблема возникла, начните с перезагрузки оборудования. Во многих случаях работа аппаратуры восстанавливается. Если это не помогло, синхронизировать временные данные невозможно, попробуйте задать правильные настройки или обратитесь в службу поддержки оператора.