Отправляет email-рассылки с помощью сервиса Sendsay

[TC] интернет-игра двух пользователей

Здравствуйте, уважаемые!

Мне нужно разобраться как организовать игру двух игроков между собой через
интернет?

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

Если этот вариант сложно реализуемый, то может быть есть более простой
способ организации такой игры?

Если трудно объяснить мне как это сделать, подскажите в какой области искать
учебный материал? смотрел организацию сетевых игр, но на первый беглый
взгляд, мне показалось, что это несовсем то. Я разумеется, могу ошибаться.

Всем очень буду благодарен за помощь,
Грызунов Александр. Самара.

Ответить   "eastreb" Wed, 27 May 2009 23:18:00 +0400 (#865144)

 

Ответы:

Здравствуйте, Александр.

Я думал над этой задачей. К сожалению нет времени реализовать
задуманное. Может быть, Вам пригодятся мои выводы.

1. Данная технология легко обобщается на многие настольные игры, но я
буду говорить о шахматах.

2. Есть две мало связанные подзадачи в этой задаче: серверная часть и
программа-клиент.

2.1. Сервер. Серверная часть обязательно должна включать в себя
систему опознавания клиента. То есть, входя на сервер, клиент должен
иметь логин и пароль, и следовательно, должен иметься механизм
регистрации. Сервер должен быть событийно управляем. То есть, он
получает от клиентов события в некоем формате, анализирует их, и
предпринимает необходимые действия по каждому событию. Сервер может
быть активным или пассивным.

2.1.1. Активный сервер. Получив событие от клиента (например,
очередной ход или предложение ничьей) активный сервер сам отправляет
событие другому клиенту. Это обеспечивает игру в реальном времени. Но
тут имеются чисто технические сложности. Для отправки по собственной
инициативе сервера, по-видимому, необходим доступ к сокетам
хост-сервера, что резко сужает круг доступных хостеров. Во-вторых,
активный сервер должен обращаться на некоторый порт клиента, что также
создаёт дополнительные сложности, например, требует от клиента
открытости порта, а у некоторых провайдеров это проблематично.
Посему, вариант активного сервера я для себя отверг.

2.1.2. Пассивный сервер отличается от активного тем, что сам ничего по
своей инициативе не отсылает. Он ждёт запросов клиента. Например, он
получает очередной ход от клиента Вася, и не отсылает его клиенту
Пете, а помещает это событие (или ряд событий) в базу данных с
указанием, кого эти события касаются, и ждёт обращения от клиента
Пети. Соответственно, клиент в этом случае должен обращаться к серверу
не только "по делу", передавая некое событие, но и просто периодически
обращаться к серверу со служебным событием "жду информации". Сервер,
получив запрос от клиента Пети, просматривает ещё необработанные
события в таблице событий, выбирает оттуда события, касающиеся Пети,
отсылает их Пете, а из таблицы их либо удаляет, либо помечает как
обработанные. Если ничего нового для Пети нет, сервер отсылает ему
событие "ничего нового".

Интервал обращений к серверу от клиента можно задавать постоянным --
секунды 3, 5, или делать его гибким, скажем первые 10 ходов с
интервалом 3 сек., а далее 10 сек. чтобы не дёргать сервер понапрасну
слишком часто. Важно понимать, что реактивное время в плохом случае
составит удвоенный интервал, плюс время на собственно отсылку пакетов
и реакцию сервера. То есть, клиент ждёт ответного хода, и каждые 10
секунд запрашивает сервер, а противник пока не делает хода, и его
клиент тоже шлёт запросы серверу через 10 секунд, соответственно,
реакция в плохом случае составит около 20 секунд. Поэтому, мне
кажется, надо попробовать интервал секунд в 5 -- 7, и на тестах
проверить другие значения интервалов.

2.1.3. Обработчик событий. В серверную программу должен входить
обработчик событий типа большо-ого свитча. И каждое событие должно
обрабатываться отдельным кейсом этого свитча. Событие представляет
собой некий идентификатор события (именно по нему идёт свитч) и набор
параметров события (набор параметров может быть пустым). В пакете
могут передаваться сразу несколько событий. В заголовке пакета
обязательно должен присутствовать идентификатор клиента. Мне
представляется удобным использовать HTML-подобный формат. Например,
пакет событий может выглядеть так:

<begin>
<user_id=12345>
<event_id="move" txt="e2e4">
<event_id="chat_msg" txt="Гроссмейстер пошёл е2-е4, надо сдаваться!">
<end>

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

2.2. Клиент. У клиент программы есть 3 принципиальные функции:

2.2.1. Поддерживать связь с сервером. Для этого форматы данных у
сервера и клиента должны быть согласованы в сторону сервера. То есть,
надо сразу закладывать в систему реакцию на устаревшую версию клиента.

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

2.2.3. Клиент должен обеспечивать пользователю максимально удобный
интерфейс.

3. Реализация. Выше описанная схема позволяет реализовать задачу на
основе обычного HTML-протокола. То есть, серверная программа суть
сайт, для определённости на PHP. Структура базы данных заслуживает
отдельного обсуждения. В качестве клиентов хорошо бы иметь что-нибудь
экзешное с одновременно удобными интерфейсами для зрячего и незрячего,
что принципиально откроет большую аудиторию. Но для начала вполне
можно обойтись и обычным браузером со скриптовой клиентской программой
на java или vbs. Для отладки даже п. 2.2.2. необязателен, только
сервер должен возвращать реальную HTML-страницу. Но, конечно, хорошо
было бы если бы сервер отсылал файл аналогичного принимаемому формата,
а клиент программа разбирала бы события, и актуализировала бы их в
интерфейсе пользователя.

Ответить   Thu, 28 May 2009 12:43:33 +0400 (#865360)

 

Приветствую всех.
Владимир пишет:

Прежде всего надо отметить, что у вас сильно сцеплены два уровня: игровое взаимодействие
и сетевое взаимодействие, что при правильном проектировании должно быть исключено.
Однако, независимо от уровня, корректнее будет говорить, что сервер получает
от клиента запрос на предоставление определенного сервеса (к тому же это будет
соответствовать семантике понятия). Термин "событие" тут неуместен.
"Событие" от "запроса" отличается:
1. событие обрабатывается асинхронно, то есть источник события не ждет, когда
обработчик события выполнит какие-либо действия, так как источник события принципиально
не нуждается ни в каких сервисах (в контексте порожденного события) -- нажатие
клавиши -- это событие, поскольку клавиатуру (драйвер и т.п.) совершенно не интересует,
как приложение будет реагировать на это событие bи если приложение проигнорирует
это событие, то на работе клавиатуры (драйвера) это никак не скажется;
2. выполнение запроса происходит синхронно, то есть клиент ждет, пока сервер
выполнит запрос и предоставит соответствующий сервис (услугу) -- обращение браузера
к http-серверу -- это запрос, так как браузер не может продолжить нормально работать,
если не получит соответствующий его запросу ответ сервера (т.е. клиент заинтересован
в получении ответа на свой запрос, в противном случае клиент выдаст сообщение
об ошибке, которое, в зависимости от реализации клиента) может быть тоже либо
событием, либо запросом...) .

Если клиент посылает запрос и не ждет, когда сервер его выполнит, то :
1. либо клиент позже посылает запрос на получение результатов предыдущего запроса;
2. либо клиент и сервер меняются местами и теперь уже бывший сервер, став клиентом,
запрашивает у бывшего клиента, ставшего сервером, определенный сервис, т.е. требует
от него, чтобы он принял данные (см. работу p2p-сетей).

Игровая модель может быть реализована и в рамках клиент-серверной парадигмы,
и в рамках событийной парадигмы, но в этой парадигме нет серверов и клиентов
как таковых, а есть два и более объектов, которые генерируют события и реагируют
на события, генерируемые другими объектами. Здесь фактически нет взаимодействия
объект -- объект, а есть взаимодействие объекта с событием, также здесь нет той
жесткой предопределенности в предназначении объектов, которая есть в модели
клиент-сервер (обслуживаемый -- обслуживающий).

Независимо от игровой модели, модель сетевого взаимодействия для сетей tcp/ip
всегда будет клиент-серверной.

Не может. То, что вы называете "пассивным сервером" , называется "сервером".
То, что вы называете "активным сервером", называется "клиентом".
Иными словами тот, кто является инициатором соединения и посылает запрос на услугу
называется "клиентом", а тот, кто находится в режиме ожидания запроса и предоставляет
по запросу соответствующую услугу, называется "сервером". Когда ваш "активный
сервер" пытается соединиться с клиентом, то он перестает быть сервером, а выступает
вроли клиента, инициирующего соединение и посылающего запрос.
В узком смысле слова, для сетей tcp/ip сервером считается тот, кто прослушивает
сокет, а клиентом -- тот, кто инициирует соединение.

На мой взгляд, тут имеются чисто терминологические сложности, порождающие некоторый
синкретизм в излагаемой модели.
Опять необходимо отделить друг от друга сетевое взаимодействие и игровое взаимодействие
(абстрагировать одно от другого). Допустим у вас игровая модель, основанная на
событиях, тогда убираем всякие "активные/пассивные серверы" и принципиально не
рассматриваем то, как происходит сетевое взаимодействие. В этом случае, например,
у нас остаются три равноправных объекта: игрок1, игрок2, шахматная доска, которые
генерируют события и реагируют или игнорируют события, порожденные другими объектами.
Переводя с русского на русский то, что вы называете сервером, в рамках данной
событийной игровой модели является шахматной доской, а то, что вы называете клиентом
-- игроками 1 и 2.

Теперь вернемся к сетевому взаимодействию:

Интернет-сокеты передают информацию в обоих направлениях, поэтому после того,
как клиент установил tcp-соединение с сервером, обмен данными может происходить
как от клиента к серверу, так и от сервера к клиенту (если, конечно, один из
участников соединение не переведет сокет в полузакрытое состояние).
Иными словами, пока соединение существует, сервер спокойно может передавать по
нему данные в направлении клиента.
Еще раз повторю, что тот, кто иницирует соединение -- это клиент, а тот кто принимает
соединение (прослушивает сокет) -- это сервер.
Поэтому, как только ваше приложение пытается установить соединение, оно из сервера
превращается в клиента и наоборот. По этой причине нет ни активных серверов,
ни пассивных, а есть просто: клиенты и серверы.
Вот пример:
Браузер -> web-приложение -> сервер mysql
Стрелки указывают направление инициативы в установлении соединения, т.е. браузер
-- это клиент по отношению к web-приложению, а web-приложение -- это клиент по
отношению к серверу mysql.
Так вот, когда ваше приложение хочет выступить в роли клиента, т.е. соединиться
с определенным портом по определенному адресу, тогда и возникает вопрос о доступе
к сокетам из php-скрипта, так как для такого соединения нужно создать сокет и
соединить его с тем портом, который на удаленной машине прослушивает серверное
приложение. Однако эта проблема не имеет никакого отношение к игровому взаимодействию,
построенному по модели клиент-сервер.

"сервер должен обращаться на некоторый порт клиента" -- для tcp/ip это оксюморон.

Это и есть сервер (ну просто сервер).

Вот этот фрагмент описывает игровую модель "клиент-сервер" (только слово событие
нужно убрать, чтобы не сбивало с толку). Иными словами, независимо от того, как
у вас реализовано сетевое взаимодействие, игровая модель выглядит так:
два клиента (игрок 1 и 2) обращаются к серверу (шахматной доске) с соответствующими
запросами и получают (сразу, то есть без разрыва соединения) соответствующие
ответы. Здесь очевидна жесткое функциональное раздление игровых объектов.
Тут можно привести аналогию с синхронным и асинхронным вызовом функций, например,
в Windows чтение/запись в файл может быть синхронным действием (поток приостанавливает
свою работу, пока функция чтения/записи не завершит соответствующую операцию
и не вернет управление) и асинхронным (когда поток продолжает свое выполнение,
а функция чтения/записи извещает его об окончании своей работы через событие
или иной сигнальный объект).
Синхронный вызов -- это модель клиент-сервер, асинхронный -- это событийная модель.
Конечно, игровая модель "клиент-сервер" и сетевое взаимодействие "клиент-сервер"
неплохо подходят для совместного использования, но тем не менее это разные уровни
приложения и их нужно абстрагировать друг от друга (причем не только умозрительно,
но и в реализации).

Здесь корректнее говорить, что у игрока есть два типа запросов:
1. запрос: примите ход (т.е. запись в базу данных);
2. запрос: сообщите ход (чтение из базы данных).
В скобках указана услуга, которую предоставляет сервер. Могут быть и другие запросы,
например, запрос синхронизации времени и так далее.
Игрок обращается со своим запросом к серверу (шахматной доске) и сразу же получает
необходимую информацию в рамках одного соединения (это и есть транзакция).

Только в варианте "клиент-сервер" это будет switch по типам запросов. Но почему
большой??? Вы же сами пишите ниже, что обработку игровой информации у вас берет
на себя клиентское приложение(т.е. приложение, которым пользуется игрок). В таком
случае серверу достаточно выступать в роли обертки для доступа к базе данных,
что в минимальном варианте требует реализации только двух типов запросов: чтение
и запись.

Ну к чему эти иносказания. Сразу надо писать -- XML :-)
К тому же, тут мог бы пригодиться xmlrpc, который поддерживается, например,
в python или php5.

На мой взгляд, такая категоричность в рассуждениях об общих подходах сомнительна.
На данный момент неизвестны ни параметры сервера, ни параметры клиентов. Более
того, такой вариант имеет подводные грабли в виде рассинхронизации позиций (причем
не только случайное, но и умышленное). При этом у вас возникнет большой ком проблем,связанный
с попыткой клиентов согласовать позиции -- даже если не принимать во внимание
накладные расходы, связанные с этим процессом, то остается вопрос: какую из позиций
надо будет считать правильной? Или в этой ситуации в процесс игры должен будет
вмешаться сервер (то есть он должен будет проанализировать все ходы до текущего
и сделать вывод о том, какая из позиций правильная)?
В общем случае, существуют две крайние точки в реализации клиентов, так называемые
толстый и тонкий клиенты.
Соответственно, первый большую часть функционала берет на себя, а сервер выступает
как промежуточный элемент, поддерживающий лишь передачу данных между клиентами.
В случае тонкого клиента большая часть функционала переносится на сервер, а клиент
занимается лишь отображением полученной информации на терминале и отправкой данных,
введенных с клавиатуры (тут возможны любые сочетания устройств ввода/вывода).
Выбор того или иного варианта не всегда однозначен и часто принимает вид компромиссного
решения.

JavaScript или Java-апплет?

А почему вы решили, что этого нельзя сделать на JavaScript и что нужно обязательно
отдавать "реальную html-страницу"?
Ajex, например, работает ровно так, как вы сказали выше. Иными словами, получить
XML-документ и обработать его в клиентском скрипте -- это вполне возможно (при
этом "реальную html-страницу" перезагружать необязательно).

Успехов. Анатолий.

Ответить   "i_chay" Fri, 29 May 2009 03:41:01 +0500 (#865641)

 

Здравствуйте, уважаемый Анатолий.

Видимо, имеет место недоразумение. Я отвечал на вопрос Александра
Грызунова. Я не предлагал ни постановки задачи, ни технического
задания, ни обсуждения, ни аргументов. Я предложил только свои выводы.
И изложил их языком, на мой взгляд, доступным для того, кому я отвечал.

Вы, Анатолий, совершено напрасно адресуете мне свои претензии по форме
и по содержанию моего письма. Я не хуже Вас знаю, что такое
клиент-серверные приложения, поскольку занимаюсь ими профессионально
более 20 лет. Не могу сказать, что в Вашем письме для меня нет ничего
нового (ваши трактовки известных терминов для меня новость, более в
психологическом плане чем в профессиональном), но полезного или
конструктивного я в нём не вижу ничего, кроме самых общих предложений
инструментов для реализации. Я конечно, могу ошибаться, но мне
кажется, ваше письмо только запутывает задачу для не слишком
квалифицированного программиста.

взаимодействие

Это ваше мнение. Я с ним категорически не согласен.

Видите ли, Анатолий, ваши трактовки понятия сервера и клиент-серверных
технологий мне представляются наивными и некомпетентными. Давайте,
сначала объясните продавцам "железа", что они продают вовсе не
серверы. Объясните всему миру, что Microsoft windows Server вовсе не
сервер, объясните что технология ICQ это не клиент-серверная
технология. (Ну как же! Ведь там сервер не отвечает на запросы
клиента, а сам вызывает клиента. А значит, и сервер, и клиенты
одновременно являются и серверами, и клиентами. Только один клиент
почему-то от других отличается по функциям, но он всё равно у Вас
клиент ;-) ) Может быть Вам кто-то и поверит. Только не надо ко мне с
этими глупостями приставать, время на ответы жалко.

Серверная программа может быть построена как обработчик запросов, как
обработчик событий, и как последовательно алгоритмическая программа. Точка.

браузера

работать,

Это -- ложное утверждение. Любой нормальный клиент предусматривает
"неответ сервера". В ответ на запрос клиент очень часто получает ответ
о том выполнен запрос или нет. Но при этом он вполне может заниматься
своими делами не дожидаясь ответа или интерпретировать неответ как
определённый ответ.

Вы просто не понимаете, что одно не исключает другого, и разные
парадигмы могут использоваться в технологиях программирования сверху
вниз и модульного. Кто ж мешает сделать клиент или сервер событийно
управляемым? Ах, это уважаемый Анатолий против! :-) Извините, это
сугубо ваши проблемы Анатолий.

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

Может, Анатолий, может :-) Насколько я Вас понял, Вы просто
произвольно и субъективно сузили понимание запроса и сервиса сервера.
А запрос может быть на предоставление сервиса по передаче информации
другому клиенту (как в ай-си-кью или в вентриле), или на выполнение
сервером операций (например, хранимые процедуры в SQL-серверах).

Вы слишком категоричны, Анатолий. Не надо выдавать своё понимание
терминов за объективную истину. Вы сколько угодно можете называть
виндоуз сервер клиентом, от этого он не перестанет ни быть, ни
называться сервером.

некоторый

Во-первых, повторю -- я не излагал никакой модели. Вы изначально
неправильно интерпретируете моё письмо.

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

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

доступе

и

А я считаю, что имеет :-) Ваше мнение против моего. Ну и что это даёт
нам или Александру? Постарайтесь, пожалуйста, либо быть более
конструктивным, либо не отнимать время на схоластические споры.

А кто здесь кроме Вас говорил о tcp/ip? Сами себе оксюмороны
придумываете, сами и разбирайтесь. :-)

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

Увы, Анатолий, их гора-аздо больше чем два :-) Соответственно и услуг
больше. И все они для сервер-программы суть события (разумеется, в том
смысле, что лично мне такой подход представляется самым эффективным).

Потому что событий связанных с игрой гораздо больше чем 2. Вот
неполный список:

Вход клиента игровой зал.
Чат в зале с отправкой и получением сообщений.
Выбор доски.
Выбор стороны белой или чёрной.
Событие готовности начать.
Ход.
Предложение ничьей.
Отклонение или принятия ничьей
Предложение отложить партию
сдача
Выход с места (чёрные или белые)
Выход из доски
выход из игрового зала
События, связанные односторонним отключениемпартнёра
и т.д. и т.п.

Во-первых, не хочу обременять начинающего программиста избыточной
информацией. Я даю её минимально для реализации конкретной задачи.
Слов нет, хорошо бы Александр изучил XML и UML; транзакции
SQL-сервера; разнообразные парадигмы и методы программирования;
проштудировал бы Винера, Дийекстра, Кнута... Тогда бы он смог сам, без
нас, решить задачу :-)) Вы хотите чтобы он всё это сначала изучил, а
потом приступал к постановке задачи и её реализации? ну-ну...

Во-вторых, я не хочу указывать чёткий формат, который требует
определённого обработчика. По моим оценкам, написать разбор простого
формата для этой задачи проще, чем осваивать какой-то определённый
формат, и связывать себя программой разбора этого формата.

Первое конструктивное предложение. К сожалению мне оно не к чему,
поскольку я этой задачей не занимаюсь. А Александру вполне может
пригодится.

(причем

На самом-то деле, у меня есть достаточно чёткое представление о
параметрах сервера и клиента. "Подводные грабли" -- это хорошо
сказано! Вкусно! Но я не вижу возможности случайной рассинхронизации
позиций, на мой взгляд это вопрос ошибок программы. Что касается
умышленной рассинхронизации позиций, то она меня не сильно заботила.
Я, как видимо и Александр, предполагал сделать минимальными усилиями
продукт с минимальным набором услуг и функций. Можно, конечно, задачу
ставить более общо: с рассчётом на выделенный сервер, с ведением
спортивных рейтингов, с анализатором fair play (мне кажется, гораздо
губительнее для интернет-шахмат использование шахматных программ, чем
умышленная рассинхронизация позиций). Такие системы есть, и можно,
например, не изобретать свой велосипед для незрячих, а пытаться
достучаться до авторов или хозяев действующих систем с предложениями
по адаптации интерфейса для незрячих. Можно и самим такую систему
попытаться реализовать. Но это очень большая работа, я имел в виду
гораздо более скромную задачу. А если начинающий энтузиаст на коленке
сляпает что-то как-то где-то работающее, на мой взгляд, это уже
хорошо, потому как ведь ничего пока нет, ни хорошего, ни плохого.

Это на выбор конкретному исполнителю. По опыту могу сказать, что
часто выбирают не что лучше, а что проще, что лучше знают.

Я не говорил "нельзя" :-) Поскольку речь здесь шла о минимальной
версии для отладки, я говорил о том как проще. Проще на мой
субъективный взгляд. Другому может оказаться проще другой вариант,
например тот, о котором говорите Вы.

(при

Ну конечно, возможно. Просто при этом Вы неявно предлагаете Александру
изучить Ajex, XML и его обработчики. Это второе конструктивное
предложение от Вас.

Очень надеюсь, что дискуссия на этом закончена. Во всяком случае,
отвечать дальше не обещаю.

Ответить   Sat, 30 May 2009 13:32:55 +0400 (#866093)