Всем привет.
Разработал для нашей компании кликер в телеграмме на php + javascript. Изначально, каждый клик сохранял в БД (mysql) и на каждый клик было 3 запроса:
1. Проверка количества кликов за последние 4 часа (было ограничение)
2. Увеличение количества очков на + 1
3. Сохранение времени клика в отдельную таблицу
На тестах все работало хорошо. При увеличении нагрузки (~ 100 + людей), БД стала не успевать и вместо условных 100 кликов людям засчитывало ~40.
После этого переделал скрипт и стал сохранять количество очков в localStorage, а время кликов в cookie. Но понимаю, что это не оптимальный вариант - люди могут заходить с двух устройств (телефон и пк). Как вариант, забирать количество кликов и их время раз в 3-5 секунд, но что делать с теми, кто быстро прокликал и вышел?
На тестах все работало хорошо. При увеличении нагрузки (~ 100 + людей), БД стала не успевать и вместо условных 100 кликов людям засчитывало ~40.
Схему таблиц в студию и примеры запросов из скрипта.
кликов людям засчитывало ~40.
Какие заголовки отправляет сервер клиенту при ajax запросе? Возможно, есть фактор кэширования запросов. Но я склоняюсь, что что-то вы делаете не правильно с СУБД.
Наилучшим вариантом для такого функционала будут сокеты, долбёжка обычными запросами по http никогда до добра не доводит. При высокой нагрузке упадёте просто. С сокетами отпадет надобность переживать, не потерял ли кто-то клики и все ли зарегало.
На примере того же хомяка, он раз в какой-то период (условно 2 секунды), отправляет количество кликов, которые пользователь накликал за это время. Соответственно, на бэкенде просто суммируется это значение с возможными проверками на накрутку (чтобы не прислали фейковое количество, которое явно за 2 секунды не прожать).
Если я правильно тебя понял, то нужно, чтобы и клики регались и тот, кто вышел - не потерял своё настоящее количество. Поэтому решение:
0. Юзер зашел в приложение выгружаешь ему его клики
1. Запускаешь setInterval (ну 5 секунд например) и когда он срабатывает отправляешь запрос на бэкенд с количеством кликов за этот период, не забывая обнулить каунтер не отправленных кликов
2. Количество не отправленных кликов дублируешь в localStorage и обнуляешь его, когда запрос уходит на бэкенд (см. пункт 1)
3. Перехватываешь событие закрытия окна/приложения и шлешь последний запрос на бэк, если не отправленные клики > 0 (этот вариант на самом деле тут по приколу, я обычно так не делаю, поскольку последний запрос не отправится, если у юзера отвалится интернет)
4. Ну и при открытии приложения смотришь, если localStorage не 0, отправляешь запрос на бэкенд
Это как один из возможных сценариев развития.
По факту, если зайдет какой-то веб разраб он сможет себе накрутить клики, просто поигравшись в девтулзах браузера и отправив нужные данные в запросе, просто помни об этом.
scooby_doe, да, я тоже думал про такое решение, но при такой реализации может возникнуть ситуация, когда пользователь с телефона сделал клики и вышел с приложения, но скрипт не успел их забрать (setInterval не прошел). После этого человек заходит с ПК и у него эти клики потеряются до того, как человек не зайдет с телефона.
По поводу накрутку - стоит валидация данных, которые приходят от телеги.
heavig2, пункт 3 может частично помочь, чтобы данные не терялись. На http запросах ничего не изобретешь, тут только сокеты помогут, прям пушить на бэк каждый клик там можешь, ничего не теряя.