PHP: выполнить действие по истечении заданного времени

#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")); , если есть какие-либо строки, выполняет a foreach для выполнения действий и удаляет их?

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.