PDA

Просмотр полной версии : Запаздывание в real-time онлайн игре


xjack
07.02.2013, 22:41
Всем доброго времени суток. В данный момент занимаюсь созданием real-time игры для соц. сети, где необходимо моментально передавать информацию о перемещении игрока всем его оппонентам. Взаимодействие клиента и сервера осуществляется через сокеты. Сервер написан на C# c использованием асинхронных сокетов.
Сообщение серверу посылается не каждый кадр а в момент нажатия и отжатия игроком клавиши(если клавишу удерживать то сообщение не передается, только в момент клика), далее траектория его движения во флешках оппонентов высчитывается . Вес сообщения минимальный - всего 10 байт.
Когда запускаю сервер и клиентов(2 экземпляра флеш) на локальном компе, то все работает идеально, движения игрока без задержек отображаются в окне оппонента. Но как только запустил серверную часть на удаленном dedicated server(i7 - 4 ядра) все стало намного печальнее. Начало движения, изменение траектории, остановка происходят с весьма заметным опозданием. Самый простой пример - игрок движется по прямой, я отпускаю клавишу - он останавливается, но в окошке оппонента продолжает бежать еще несколько кадров. А когда начинаешь прыгать там вообще вся траектория сбивается.
Вопрос - что я делаю не так? По идее, если на локальном компе все ок, значит скорость работы серверной части нормальная. Объемы передаваемой по сети информации минимальны. Тестирую пока на двух игроках. В чем может быть проблема?

stasuss
07.02.2013, 23:16
а может все таки дело в пинге до сервера?

xjack
07.02.2013, 23:23
Пинг где-то от 80 до 115.

-De-
08.02.2013, 01:35
Это не так мало. 115 - это более 4 кадров при 40фпс. Замерьте время между отправкой сообщения и приходом реакции от сервера (и ещё можно отдельно между отправкой и собственно рендером результата).

iflamberg
08.02.2013, 14:11
Дык, это. Повсеместно это. А лаг вы, кстати, внутриигровой измеряете или просто пингуете? Потому что это разные вещи. Tcp, к сожелению, накладывает еще и свои ограничения, ну сами должны знать, ожидание устаревшего пакета и т.д. Поэтом и придумывают всякие алголитмы лаг компенсации и сглаживания-интерполяции, но в общем-то не очень-то и помогает. При пинге больше 200 - играть не комфортно, как ни старайся(ну это для шутеров, для рпг типа WoW или rts не так критично).

P.S. И не забудьте отключить алгоритм Нагля в настройках тсп серверного приложения. Хотя черт его знает, помогает ли, но все рекомендуют =)

xjack
08.02.2013, 16:24
В общем, сегодня поэкспериментировал с измерением времени, так что теперь привожу конкретные данные.
в первом окошке засек время отправки сообщения о нажатии/отпуске клавиши, во втором - время его получения в миллисекундах.
И вот результаты: когда интервалы между сообщениями длительные(например нажал клавишу, несколько секунд удерживаю затем отпускаю), до оппонента они доходят примерно через 80 мс каждое. А теперь самое интересное -когда нажимаю и сразу же отпускаю(обычный клик). Key_down доходит также где-то через 80 мс, а вот key_up через ~300 мс! Вот например результаты последнего замера: Отправка (key_down:0, key_up:52), получение: (key_down:78, key_up:365(!!!)). Похоже дело не только в пинге.

iflamberg
08.02.2013, 16:43
Э, так дело не покатит. Какие key_down, key_up? У тебя на сервере и на клиенте из-за лагов сети совершенно непредсказуемый промежуток времени между этими событиями произойдет. Изменение координат персонажей надо пересылать. А на клиенте полученные данные интерполировать, иначе персонаж скачками будет перемещаться. Вам бы теорию почитать. Много теории. Гуглите programming multiplayer games, interpolation, lag compensation, predicting, tcp vs upd. Конкретных статей не посоветую.

xjack
08.02.2013, 17:23
Сделал замер времени на сервере - оказывается он УЖЕ получает данные сообщения с интервалом 280-300 мс, хотя ушли они с интервалом 50 мс. Кто может подсказать в чем проблема такого сдвига по фазе? Может быть есть некая минимальная задержка с которой TCP отправляет сообщения.

iflamberg
08.02.2013, 17:39
Tcp/ip - протокол с гарантированной доставкой пакетов. Это означает, что 1) пакет не окажется в буфере, пока не сойдутся чексуммы 2) если не отключен алгоритм Нагля, то сервер не будет передавать следующий пакет в буфере отправки, пока не получит от клиента подтверждения о том, что предыдущий пакет доставлен без ошибок(это происходит на уровне протокола, естественно).
Вот и считай. Пинг от тебя до сервера, скажем 100мс. Соответсвенно, от клиента до сервера и к другому клиенту - 200мс. С ожиданием подтверждения о доставке пакета - еще больше. Такая математика.

KumoKairo
08.02.2013, 17:42
xjack,Скорее всего дело в работе сервера.
Когда мы делали real-time клиент-серверное приложение на Flash + Java(сервер), пинг был 50-80 мс, с учетом того, что сервер, фактически, в соседнем городе.
Может быть проблема с удаленным сервером, может быть что-то еще.

Попробуйте запустить сервер у себя, и проверить с кем-нибудь из собственного горда работу приложения
______
А да, и потом мы все таки отступили от технологии socket server в пользу P2P. Для P2P соединений флеш использует UDP протокол.
Поскольку полноценный socket server в любом случае имеет верхнюю границу онлайна при передаче данных в режиме реального времени..

xjack
08.02.2013, 17:49
хм..
1)А этот алгоритм Нагля достаточно отключить только на сервере или на машине клиента тоже?
2) Возможно тогда есть смысл использовать UDP вместо TCP?

iflamberg
08.02.2013, 17:59
Я не знаю, можно/нужно ли отключать алгоритм Нагля на клиенте, но в любом случае реализация Сокета в флеше этого не дает сделать.
На сервере, ну не знаю, в gcc под никсами это просто

const int on=1;
setsockopt (sock,IPPROTO_TCP,TCP_NODELAY,&on,sizeof(on));


А UDP в флеше нет. В air есть, но я не делаю десктопные/мобильные приложения и мне как-то не тепло и не холодно от этого.

KumoKairo
08.02.2013, 18:05
iflamberg, технология P2P во флеше полностью построена на UDP
Только при подключении к сокет серверам требуется использовать TCP

iflamberg
08.02.2013, 18:07
У меня вот все как-то руки не дойдут до p2p.

caseyryan
08.02.2013, 21:08
xjack, я вот был немного удивлен от первого сообщения этой темы. Вы делаете клиент-серверное приложение с реалтаймом, и не знали о такой распространенной проблеме? Как такое возможно вообще?
Я об этом знал когда еще читал теорию, и до практики было как до луны пешком.

Конечно дело в первую очередь в пинге. Надо разрабытывать алгоритмы предположительного расчета на клиентах. На основе пинга надо заранее узнавать сколько, допустим, персонаж может пройти пиеселей с определенной скоростью, до прихода следующего пакета. Все не так просто как может показаться изначально. Простой передачи пакетов не достаточно.
На счет самого физического сервера, на нем стоит винда? Если да, то возможно ее фаерволл играет некоторую роль в притормаживании.
У меня есть опыт работы с win server 2008r2 и 2003, и с линуксами в качестве серверных платформ. Линуксы всегда работали гораздо быстрее винды, даже если фаервол отключал. Сейчас я даже не рассматриваю винду как серверную платформу для своих игр. Только линукс.

-De-
09.02.2013, 19:39
Тупой вопрос, а вы socket.flush() делаете? Про остальное вродь написали уже.

xjack
09.02.2013, 22:11
Caseyryan Пинг в 80 мс не был бы проблемой. А проблема в том что рядом идущие пакеты с дистанцией 50 мс идут ДО сервера слишком разное время и разница >200 мс. Первый доходит как и должен за 80, второй с задержкой. Мне же нужно чтобы шли примерно одинаковое время, пусть это будет хоть 150 мс. В случае большого интервала между сообщениями они ВСЕГДА доходят примерно за 80 мс.
-De- flush делаю, хотя тоже не сразу до этого дошел при изучении сокетов =)

caseyryan
10.02.2013, 08:35
Мне же нужно чтобы шли примерно одинаковое время, пусть это будет хоть 150 мс. В случае большого интервала между сообщениями они ВСЕГДА доходят примерно за 80 мс.
Так не бывает. Не надо делать на это ставку. Попробуйте хотябы ping ya.ru -t выполнить. Интервалы будут примерно одинаковыми, но время от времени будут возникать задержки. Надо при каждом сообщении расчитывать пинг и делать корректировки.

xjack
14.02.2013, 23:27
В общем пошарив по инету, понял что проблема именно в невозможности отключить алгоритм Nagle во флеш, она реально существует и доставляет много геморроя как раз разработчикам интерактивных реал-тайм приложений.
caseyryan, На случай сбоев "время от времени" у меня вместе с каждым нажатием клавиши на всякий случай передаются координаты, так что возможность корректировки предусмотрена. Но постоянное отставание на 200 мс - это уж как-то совсем не айс.

Может кто подскажет, существует ли эта проблема при работе через медиа-серверы? А то уже начинаю думать о переходе на silverlight.

KumoKairo
15.02.2013, 18:13
У нас клиент-серверное приложение с сервером на Java работала с нормальной задержкой, вы скорее всего не там копаете. Пробовали тестировать приложение на своем сервере? Чтобы все узлы, включая сервер, были в одном городе?