Единственный способ предотвратить мошенничество - это не доверять клиенту вообще , а просто рассчитать конечное время на сервере как время, затраченное до отправки задачи клиенту после получения результат.
Это также означает, что в последний раз должен включать некоторые задержки передачи по сети, как бы несправедливо это ни казалось: если вы попытаетесь как-то их компенсировать, клиент всегда будет притворяться, что страдает от задержки, чем на самом деле.
Однако вы можете убедиться, что задержки в сети не станут неожиданностью для пользователя. Ниже приведен простой подход, который полностью предотвращает мошенничество, при этом, учитывая некоторые умеренные предположения о тактовых частотах и задержках в сети, время показа на стороне клиента при представлении результатов должно приблизительно соответствовать окончательному времени, рассчитанному на сервере:
- Клиент запускает таймер и запрашивает задание с сервера.
- Сервер записывает текущее время и отправляет задачу клиенту.
- Пользователь завершает задание.
- Клиент отправляет результат на сервер и (опционально) останавливает таймер.
- Сервер принимает результат и вычитает метку времени, сохраненную на шаге 2, из текущего времени, чтобы получить окончательное время.
- Сервер отправляет последнее время клиенту.
Хитрость в том, что клиентские часы запускаются до , когда задача запрашивается с сервера. Если предположить, что задержка односторонней передачи по сети между шагами 1 и 2 и шагами 4 и 5 примерно одинакова (и что часы клиента и сервера работают примерно с одинаковой частотой, даже если они не синхронизированы), время с шага 1 до 4, рассчитанного на клиенте, должно соответствовать времени, рассчитанному на сервере с шага 2 до 5.
С психологической точки зрения, возможно, было бы даже неплохо оставить клиентские часы включенными после шага 4, пока не будет получено последнее время от сервера. Таким образом, когда текущие часы заменяются последним временем, прыжок, скорее всего, будет обратным, что сделает пользователя счастливее, чем если бы время прыгнуло даже немного вперед.