#php #time #execution
#php #время #выполнение
Вопрос:
Доброе утро / день / вечер, Интернет. В настоящее время я разрабатываю wap-игру и столкнулся с проблемой: применение долгосрочных эффектов к другим игрокам. Позвольте мне объяснить.
Если пользователь использует «мгновенную» способность, это просто обычная командная ссылка executeAbility()
; Если пользователь произносит заклинание, скрипт выполняет следующее:
setPlayerState('casting');
sleep($cast_time);
executeAbility();
Однако это всего лишь простая часть. Теперь, если мы перейдем к некоторым более продвинутым техникам, например, наложению проклятия на игрока, я потеряюсь. Я уже рассматривал следующую возможность:
$time=$_SERVER['REQUEST_TIME'];
$time_when_the_curse_finishes=$time $curseDuration;
updateEnemyCurses($curseID,$endTime);
if ($time<$endTime) removeCurse();
Это может выглядеть красиво и все такое, но при этом не учитываются две вещи: если пользователь вышел из системы и снова вошел в систему через 2 часа, он проведет целых два часа проклятым, и этот метод не может поддерживать эффект каждые x секунд для проклятий типа y секунд. Например:
Проклятие Один. Вы получаете 1 урон каждые 2 секунды в течение 10 секунд.
Подводя итог, мне просто нужен совет или два, как я мог бы сделать строку выше возможной. Само проклятие должно было бы проверять свое время глобально (не при перезагрузке страницы) и иметь возможность выполнять запросы (в данном случае тики повреждения) каждые x секунд, пока оно не будет удалено через 10 секунд.
Я заранее благодарен за любые советы, предлагаемые здесь!
Комментарии:
1. Я думаю, ты хочешь получить работу в cron…
2. Я тоже думал о заданиях cron, но разве создание файлов для заданий cron каждую секунду для ~ 1000-4000 человек в Интернете не убило бы серверы?
3. Кроме того: используете ли вы PHP «sleep ()» в своем скрипте? С точки зрения перспективы UX, это может быть не очень хорошей идеей (если только это не вызов ajaxy ..)
4. usleep, если быть более точным. Я знаю, что это не совсем идеальный метод, но на данный момент он выполняет свою работу .
Ответ №1:
Возможно, вы захотите изучить настройку скрипта cron для этого типа «обслуживания».
Он может выполняться с фиксированным интервалом (т.е. каждую секунду) и обрабатывать проклятия и т. Д. Эффекты для всех игроков
Начните здесь 🙂 http://en.wikipedia.org/wiki/Cron
Редактировать: как упоминали другие (@mark-b), лучше уточнить: используйте cronjob для одного скрипта, который управляет всей работой, а не несколькими cronjob для каждой части работы.
Комментарии:
1. Я переформулирую свой вопрос из поля для комментариев в верхней части страницы: я тоже думал о заданиях cron, но разве создание файлов для заданий cron каждую секунду для ~ 1000-4000 человек в Интернете не убьет серверы? (без иронии или неуважения, мне просто любопытно.)
2. Все зависит от выполняемых скриптов. И ваше оборудование .. и т.д. 🙂 Это определенно не редкость, чтобы сделать что-то подобное. Если вы правильно структурируете свои таблицы и имеете эффективную индексацию, это не должно быть так уж плохо.
3. Это, безусловно, интересно. Определенно попробую это вместе с идеей An0n, опубликованной выше, чтобы увидеть, какая из них работает быстрее.
4. Как упоминалось в ответе Марка, вы не должны создавать задание cron для каждого действия, вы настраиваете задание cron общего обслуживания, которое обрабатывает все сразу.
5. Это, однако, может быть не вариант, поскольку я только что узнал, что CRON может быть установлен только с точностью до одной минуты, и проверка должна выполняться каждую секунду (самый медленный perdiod, который я могу себе позволить).
Ответ №2:
Я полностью понимаю вашу проблему, потому что здесь, на работе, мне пришлось иметь дело с функцией, которая требовала решения, которое могло бы вам помочь. Что я сделал, так это настроил таблицу БД, в которой хранились все требуемые / ожидающие действия и владелец действия. В этой таблице была временная метка, и через определенный интервал я проверил, какие действия требуется выполнить для этого пользователя. Другие пользователи также проверили эту таблицу и удалили прошлые действия, которые не были восстановлены (т. Е. Владелец этого действия вышел из системы). Проблема здесь заключалась в том, что делать, если ни один пользователь не был зарегистрирован вообще, и что я сделал, так это то, что когда пользователь входит в систему, он сначала проверяет таблицу ожидающих действий и при необходимости очищает ее. Я надеюсь, что смогу дать вам некоторое представление. Удачи!
Комментарии:
1. Спасибо за ваш ответ. Поправьте меня, если я ошибаюсь: следуя вашему примеру, я бы создал таблицу с полями
id,function,time
, в которыхid
указан идентификатор пользователя,function
код php, который будет выполняться, иtime
временная метка. При каждом нажатии, которое любой пользователь делает в любом месте, скрипт выполняет запрос:$sql=mysql_fetch_assoc(mysql_query("SELECT function,id FROM actions WHERE time<CURRENT TIMESTAMP"));
, если есть какие-либо строки, выполняет aforeach
для выполнения действий и удаляет их?2. На самом деле мое решение включало таймер (это было приложение под Adobe Flex), который проверял таблицу каждую минуту, вы должны проверять свои ожидающие действия каждую секунду и удалять прошлые действия от других пользователей. Если это мобильное приложение, вы можете использовать некоторый javascript для локального хранения ваших текущих / ожидающих действий и просто проверять те, которые ожидаются от других пользователей. Я уверен, что есть более приятный / оптимизированный способ сделать это по вашей технологии, но у меня был только общий хост и php с flex для этого.
3. Поскольку я стараюсь быть как можно более мультиплатформенным, а большинство старых телефонов не поддерживают javascript, единственное хранилище, которое у меня будет, это
$_SESSION
. Говоря об этом, я не верю, что это был бы правильный путь, поскольку он просто искал бы ваши собственные действия, а не другие, делая «тики» запаздывающими.
Ответ №3:
Лучше всего реализовать очередь событий в базе данных. Вместо того, чтобы создавать задание cron для каждого действия, которое необходимо выполнить пользователю или пользователем, вы просто добавляете запись в очередь заданий БД.
Затем ОДНО задание cron может извлекать задания из этой очереди и обрабатывать их. Итак, для вашего события ‘curse’ вы должны установить флаг curse для пользователя и запланировать выполнение задания со now 5 minutes
словами «удалить curse X из user Y».
Задание cron будет периодически запускаться (возможно, с любой скоростью «галочки» в вашей игре) и запрашивать список заданий, которые необходимо выполнить в этот конкретный период времени.
Комментарии:
1. Марк, я считаю, что ты только что дал мне идеальный ответ. Однако мне нужен один маленький совет. Как вы думаете, какой минимальный период cron я мог бы установить, чтобы не сжечь компьютер моего хостинг-провайдера? Будет ли 0,3-0,5 с слишком низким?
2. cron имеет детализацию в 1 минуту. Если вам нужны более короткие интервалы, вам нужно будет выполнить некоторое планирование в скрипте: Cron запускает скрипт, затем скрипт запускается / спит с любыми интервалами в несколько минут, которые вам нужны.
3. Будет ли cron поддерживать бесконечные циклы? Например.
while (1==1)...
?4. В этом случае вместо этого вам понадобится демон — фоновое задание, которое не завершается. Cron предназначен для кратковременных повторяющихся заданий, которые запускаются, что-то делают, а затем завершаются. Демоны были бы гораздо лучшим выбором, если вам нужна детализация <1 минуты при обработке.
5. Которые, я сомневаюсь, поддерживаются провайдерами общего хостинга, которые я буду использовать в начале моего проекта, но я верю, что это станет правильным решением, как только он продвинется. Если PHP настроен на ipe out, скажем, через 65-70 секунд, но задание cron проверяет базу данных каждую секунду 60 раз, после чего cron перезапускается, простой
function(); sleep();
выполнил бы работу правильно, не так ли?
Ответ №4:
Вы знаете gearman? Я думаю, вам нужно создавать асинхронные задания.
посмотрите на: http://php.net/manual/en/book.gearman.php
Комментарии:
1. Спасибо за ваш быстрый ответ, но сначала мой проект будет сохранен на общем хосте, и, боюсь, я не смогу получить доступ к Gearman.