Создание онлайн-игры: основы
Существует две основные схемы организации онлайн-игр.1. Клиент – сервер.
Есть множество клиентов, которые обмениваются информацией, передавая ее серверу, а сервер в свою очередь отправляет информацию другим клиентам. Это самая распространенная схема, она всегда используется в веб-серверах и онлайн-играх. Минус всего лишь один: нагрузка на сервер. Схема выглядит следующим образом:
Рисунок 1. Схема «клиент – сервер».
2. Клиент – клиент.
Тут все проще: клиент соединяется с другим клиентом, и они обмениваются информацией. В этой схеме минусов больше. Мало того, что эта схема поддерживает только двух клиентов, так еще если увеличить их количество, то на одного клиента будут приходиться все остальные. Т.е. нагрузка на сеть и вычислительные способности каждого клиента будут равны нагрузке на сервер. А если у нас в игре 60 клиентов, то каждый другой будет обрабатывать все 59 других, а это занимает много времени. Поэтому если и использовать эту схему, то разве что для игры на двоих, например, шахматы.
Рисунок 2. Схема «клиент – клиент».
Итак, разберемся все-таки, что делает сервер.
Что есть сервер?
Сервер - это такая вот штука, которая прослушивает нужный порт на предмет подключения. Порт - это точка доступа к серверу, к которой подключаются клиенты. Например, веб-сервер нашего уютненького
Код:
|
И получим HTML-код:
Код:
|
Клиент подключился к серверу esate.ru, сервер отправил ему ответ и отключил клиента от себя. Типичное поведение веб-сервера. Сразу стало ясно, что нам нужно, чтобы написать простой сервер. Нам нужно прослушивать определенный порт на наличие клиентов, как только он появится – решать, что с ним делать, но этим мы займемся чуть позже.
Мы будет использовать протокол
У платформы .NET есть класс для организации сервера. Называется он
Для начала создадим консольный проект на версии .NET Framework 3.5, назовем его, например, EsateGameServer (первое, что пришло в голову).
И еще некоторые приготовления: класс, в котором содержится метод Main() назовем KernelModule. Класс сервера ServerModule.
Начнем.
В "ядре" сервера создаем глобальную ссылку на наш класс ServerModule.
Код:
|
А вот код класса ServerModule:
Код:
|
В ядре пишем в метод Main() следующие строки:
Код:
|
Теперь давайте скомпилируем и попробуем подключиться к нашему серверу с помощью telnet'а. Открываем консоль, и вводим:
Код:
Жмем Enter и в окне telnet'a получаем пустое окно, а в окне нашего сервера получаем сообщение о том, что клиент соединился с сервером. Отлично, если всё получилось именно так.
|
Мы написали простой сервер, который прослушивает 256 порт, но, если мы попробуем открыть второе окно telnet'a и присоединиться к нашему серверу, клиент не подключится. И правильно, мы ведь прослушиваем 256 порт в одном потоке, поэтому как только сервер словил клиента, он начинает обмен информацией, а про прослушку порта для других клиентов забывает.
Значит, нам необходимо сделать сервер многопоточным для одновременной обработки большого количества клиентов. Об этом и многом другом подробнее в следующие части.