Проведение временных заданий на веб-сайте - лучшая практика?
Каков наилучший способ реализации временной задачи в среде веб-сайта (asp.net)? Скажем, нажатие кнопки блокирует ее на 4 часа или на день. Как мне реализовать процесс подсчета этих 4 часов (или 1 дня) и разблокировки кнопки)?
Имейте в виду, что это веб-сайт: я
- сохранить текущую метку даты и времени в БД (я захожу на сайт как зарегистрированный пользователь)
- каждый раз, когда я захожу на страницу с кнопкой, я получаю штамп и продолжительность
- и посчитайте, сколько мне еще ждать, пока кнопка не будет разблокирована.
(И, возможно, реализовать счетчик обратного отсчета JS (например), который будет отображаться рядом с кнопкой)
Я бы предположил, что использование переменных сеанса или файлов cookie - плохая идея, поскольку я могу закрыть свой веб-сайт или удалить свои пользовательские данные и, таким образом, потерять все вышеперечисленное.
4 ответа
Поскольку ваше требование заключается в том, чтобы поддерживать это между сеансами, то оно обязательно должно быть в БД.
база данных
Добавить LockedUntilUtc
столбец, который указывает дату / время, которое кнопка должна разблокировать. Еще лучше, назовите столбец для представления бизнес-модели. Возможно, вы пишете HR-приложение, в котором есть процесс утверждения повышения, и есть обязательный 7-дневный период ожидания, прежде чем менеджер сможет опубликовать повышение, чтобы разрешить HR просматривать, и кнопка помечена как "Опубликовать повышение", в этом случае я назвал бы что-то вроде PublishRaiseAvailableUtc
,
Я имел дело со многими подобными сценариями, и часто проще использовать дату / время, когда должно произойти событие. В отличие от сохранения начала таймера и необходимости всегда добавлять 7 дней каждый раз, когда вам нужно сделать расчет.
UI
Отправьте это значение вниз со страницы как скрытое значение. Напишите javascript, используя фреймворк по вашему выбору, или просто так setTimeout
который будет срабатывать, чтобы разблокировать кнопку в этот момент времени.
Не беспокойтесь о том, что пытаетесь придумать изощренный способ не дать пользователю разблокировать кнопку, манипулируя HTML. Вы должны предположить, что они могут разблокировать кнопку, если приложат к ней усилие. Учитывая это предположение, нам нужна серверная логика для проверки запроса.
Проверка почты на сервере
Когда пользователь нажимает кнопку и POST отправляется на сервер, то код на стороне сервера должен получить значение PublishRaiseAvailableUtc
из базы данных (не доверяйте значению, опубликованному из скрытого поля), и сравните его со временем сервера. Т.е. время сервера должно быть больше чем PublishRaiseAvailableUtc
при условии, что вы сравниваете время UTC.
Не полагайтесь на проверку на стороне клиента, что кнопка заблокирована / разблокирована. Всегда проверяйте на стороне сервера, что щелчок произошел в течение допустимого времени. Это не позволит кому-либо "взломать" страницу, чтобы разрешить щелчок за пределами допустимого окна.
Вы первая проблема в вашем подходе. Вам не обязательно беспокоиться о том, сколько времени пройдет, пока вы не сэкономите время, но вы определенно хотите, чтобы ваша кнопка изменилась, когда придет время.
Я могу предложить загрузить значение DateTime из базы данных, поместить его где-нибудь на странице, где JavaScript сможет его прочитать. Теперь единственная проблема заключается в том, что некоторые пользователи могут найти и изменить это значение, чтобы пропустить таймер. Я лично не знаком со способом обойти это легко, но вы должны быть в состоянии найти решение.
Если у вас есть значение, читаемое JavaScript, цикл, вероятно, будет лучшим выбором для проверки текущего времени по сравнению с вашим сэкономленным временем, а затем выполнения любого действия, которое вы захотите.
do..while
петля, вероятно, подойдет вашим потребностям- Чтобы избежать проблем с производительностью, используйте
setTimeout
задержать каждую итерацию цикла. Задержка не должна быть очень значительной. - В цикле извлеките текущую дату и время, затем сравните их с датой и временем, сохраненными в базе данных. Если текущая дата и время больше, выполните свое действие.
Теперь моя идея не может быть оптимальной, но я чувствую, что это, по крайней мере, шаг в правильном направлении. Я также предлагаю цикл, чтобы пользователю не приходилось обновлять страницу, чтобы увидеть, какие изменения произошли в результате выполненного действия.
Я думаю, что лучший способ сохранить день, когда кнопка снова разблокируется. И каждый раз, когда страница загружается, извлекайте эту информацию из БД, чтобы проверить, должна ли она быть заблокирована или нет.
Другой возможный способ - использовать переменную приложения. Но я не рекомендую этого, потому что данные хранятся в памяти и потому, что если вы перезагрузите приложение или сервер, данные будут потеряны.