Какой протокол выбрать для пошагового игрового сервера - PullRequest
9 голосов
/ 28 июля 2010

Я пишу игровой сервер для пошаговой игры на Java.Вот факты:

  • Скорость игры низкая, поэтому клиенты должны отправлять данные, скажем, каждые 8 ​​секунд, и эти данные в большинстве случаев являются лишь небольшим инкрементным обновлением (несколькодюжина байт), кроме ситуаций, таких как присоединение к игре или список доступных игр и т. д.
  • Сервер должен поддерживать большое количество игроков, скажем 1000, которые играют в одну из нескольких сотен игр
  • Когда игрок делает ход, другие игроки в той же игре должны быть уведомлены о ходе.Максимальное количество игроков в игре составляет около 10

Прежде всего, я исключил UDP из своего списка опций, так как мне нужен надежный протокол, потому что в редких случаях мне действительно нужно отправлять некоторые данные, которые не могутумещаются в один пакет, и я не хочу беспокоиться о слиянии пакетов и подобных вещах, отслеживая порядок поступивших пакетов и другие вещи низкого уровня.

Таким образом, дилемма заключается в том, использовать ли TCP или HTTP.

Попытка TCP # 1

Соединение между клиентом и сервером (и наоборот).-верса) открыта все время.Таким образом, когда игрок делает ход, сервер может легко уведомить других игроков в игре, какой ход был сделан.Главное, что меня беспокоит при таком подходе, - это целесообразно или вообще возможно иметь до 1000 соединений и сокетов постоянно открытыми?

TCP попытка # 2

Альтернатива, о которой я подумал, заключается в использовании отдельного соединения / сокета при каждом запросе от клиента.Клиент откроет соединение, отправит небольшие данные на сервер и закроет это соединение.При таком подходе я могу иметь пул потоков фиксированного размера, скажем, 10, и обрабатывать запросы клиентов в каждом потоке отдельно, так что в любой момент может быть открыто не более 10 разъемов / сокетов.Но есть две вещи, которые меня беспокоят таким подходом:

  1. дороговизна открытия / закрытия соединения с клиентом
  2. способ уведомления других игроков в игре, так как соединениедля них, скорее всего, закрыт.Каждый из них должен в этом случае «опросить» сервер на предмет обновления, скажем, каждую секунду.

Какова стоимость установления сокета / соединения TCP?Это дорогостоящая операция или она выполняется всего за несколько мс (или меньше)?

HTTP

  1. Было бы много служебных данных, если бы ябудет отправлять новый GET / POST просто для отправки нескольких байтов?
  2. Могу ли я сохранить 1000 HTTP-подключений к клиентам одновременно, а затем использовать AJAX или аналогичные вещи для уменьшения накладных расходов?В таком случае, будет ли 1000 одновременных подключений представлять значительную проблему в отношении пропускной способности / производительности?

Я открыт для предложений / рекомендаций любого рода.

Ответы [ 8 ]

5 голосов
/ 29 июля 2010

Только для вашей информации: HTTP - это TCP. Конкретный протокол, который использует TCP, то есть. HTTP основан на TCP, точно так же, как TCP основан на IP и т. Д. Таким образом, на самом деле вы выбираете между HTTP по TCP или пользовательским протоколом по TCP. Вы правы, что UDP плохо подходит здесь.

Если вы пишете сервер самостоятельно, многие из преимуществ использования HTTP исчезают. Основным преимуществом HTTP является то, что уже имеются высоко оптимизированные серверы, поэтому вы можете использовать его как простую и эффективную систему RPC. Но если вы пишете сервер самостоятельно, вы вряд ли достигнете эффективности подобных Apache, поэтому вам нужно спросить, почему вы просто не выбрали бы более простой протокол для использования? Кроме того, хакерство по принципу «только для извлечения» HTTP может показаться неправильным.

Имея это в виду, я бы просто использовал более легкий протокол по TCP. Вы получаете больший контроль над соединениями и можете уведомлять заинтересованные клиенты об обновлениях, не требуя, чтобы они запрашивали изменения. Вы также можете потерять издержки HTTP-запроса / ответа, что в большинстве случаев является излишним. Вместо этого вы можете использовать довольно простой заказной протокол, возможно, основанный на XML или JSON, или, возможно, один из существующих доступных методов RPC.

3 голосов
/ 28 июля 2010

Я вижу, что вы смотрите на очень "низкий уровень". Вы пытались использовать что-то на более высоком уровне, что-то вроде http://code.google.com/p/kryonet/ (также разработанное для игр)? (а может быть найдены плохие показатели?)

Я думаю, что результаты, полученные KryoNet, довольно хорошие, и их API очень быстро программировать.

1 голос
/ 30 июля 2010

Ваша «Попытка # 1» в порядке - нет ничего плохого в том, чтобы иметь 1000 открытых соединений (весьма обычно для одного сервера IRC иметь более 100 000 одновременных открытых соединений TCP).

(Вы можетеобнаружите, что некоторые параметры ОС необходимо настроить по мере приближения к этому числу - например, в UNIX, как правило, установлен предел по умолчанию для каждого процесса, открытый для каждого процесса, но его достаточно просто изменить).

1 голос
/ 28 июля 2010

HTTP ИМХО.Вы сможете пройти через любой прокси.Аутентификация может быть выполнена простой и с использованием HTTP-сеансов или файлов cookie один раз.

Не беспокойтесь о возможностях сервера - большинство современных серверов могут обрабатывать тысячи одновременно работающих клиентов.

1 голос
/ 28 июля 2010

Предполагается, что на сервере одновременно может быть открыто около 20 000 сокетов.Если вы решите использовать http, вы можете использовать новые функции комет tomcat 6+ или jetty 6+, в противном случае поток будет выделен для каждого запроса.

0 голосов
/ 30 июля 2010

Я хотел бы предложить, что если вы делаете пошаговую многопользовательскую игру с довольно маленькими (<50K) игровыми пакетами, вам следует рассмотреть возможность использования XMPP / Jabber. Вот несколько причин, по которым я думаю, почему </p>

  • Протокол более высокого уровня (XML), такой как HTTP, где вам не нужно работать с битами и байтами, если вы не хотите.

  • Встроенное присутствие, лобби (с MUC), механизм pubsub, управление пользователями / аутентификация, чат и т. Д. Список можно продолжить ...

  • Не нужно беспокоиться о написании масштабируемого сервера самостоятельно. Большинство серверов Jabber поддерживают плагины. Просто напишите плагин и позвольте серверу масштабировать его для вас; немного похоже на HTTP-сервер

  • XMPP - это расширяемый протокол. Вы можете нести свои игровые данные как часть загрузки чата. Брандмауэр дружественный и большинство серверов поддерживают BOSH

  • Близко к реальному времени и довольно надежно.

  • Бесплатный клиент с открытым исходным кодом (smack) и сервер (openfire) - на Java

0 голосов
/ 29 июля 2010

Просто используйте TCP-сокеты, одно постоянное соединение для каждого клиента, а также поток для ввода / вывода. Затраты на потоки не слишком высоки (Linux выделяет по умолчанию 48 КБ для новых стеков, поэтому для клиентов 1 КБ потребуется 48 мегабайт, для Windows - 2 Кбайт IIRC), ваш код будет намного более чистым и простым для выполнения, и вы будете автоматически масштабируется с ядрами процессора. Если вы беспокоитесь о брандмауэрах, изучите HTTP CONNECT и HTML 5 WebSockets.

0 голосов
/ 28 июля 2010

Установка сокета TCP довольно дешевая операция.На самом деле, общая модель HTTP заключается именно в этом.Вы никогда не должны держать HTTP-сокеты открытыми постоянно.Ajax-вызовы, HTTP-вызовы предназначены для того, чтобы их можно было открывать и закрывать как можно быстрее, чтобы можно было обработать следующий запрос.

Я не понимаю, почему дизайн опроса здесь не идеален.Опрос, когда пользователь оставляет экземпляр игры обратно в основной список игр для текущего статуса.Опрос каждые 15 секунд или около того, когда пользователь находится в основном списке игр.Убедитесь, что сервер обрабатывает этот опрос быстро, быстро - если возможно, менее миллисекунды.

Многие веб-серверы имеют жесткий лимит в 256 подключений одновременно, хотя недавно я видел это на уровне 1024 на некоторыхсервера.В любом случае, вы никогда не должны приближаться к этому пределу.Если ваше программное обеспечение хорошо оптимизировано для скорости, ни одно соединение не должно быть открыто более миллисекунды или двух, и не должно быть никакого способа приблизиться к количеству пользователей, требуемому для использования 256 сокетов.

Единственная проблема в скорости - это то, сколько времени занимает ваше серверное программное обеспечение для выполнения запросов.Затраты на установку сокета и его закрытие не имеют ничего общего с затратами на серверный код, который вы пишете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...