Синхронизация переменной между клиентом и сервером - PullRequest
3 голосов
/ 19 октября 2008

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

  1. Клиент отправляет, скажем, 23 на сервер.
  2. Сервер получает 23, проверяет его и увеличивает свой счетчик до 23.
  3. Сервер возвращает клиенту код All-Okay

-BUT-

На пути от сервера к клиенту код возврата будет поврежден. Таким образом, клиент думает, что сервер не обновил свой счетчик, и поэтому оставляет счетчик на стороне клиента равным 23. С этого момента клиент и сервер не синхронизированы.

Кто-нибудь знает какие-либо надежные схемы, которые работали бы перед лицом таких возможных коррупции / ошибок?

Спасибо
Cameron

Ответы [ 3 ]

2 голосов
/ 19 октября 2008

Вместо использования линейно увеличивающегося счетчика, вы можете использовать случайное значение "nonce" из хороших 64 бит энтропии или более Когда сервер получает запрос от клиента, сервер проверяет, соответствует ли одноразовый номер последнему, который он отправил клиенту. Если это так, то запрос обрабатывается, и сервер генерирует новое случайное значение nonce для отправки в ответе.

Сервер может хранить два последних одноразовых значения для отправки клиенту. Если клиент отправляет старое значение, то сервер предполагает, что самое последнее сообщение клиенту могло быть потеряно.

Приведенный выше метод предполагает, что ваша цель состоит в том, чтобы два разных клиента не использовали одинаковые учетные данные для связи с сервером. Преимущество использования метода nonce заключается в том, что следующее значение не может быть легко предсказано.

1 голос
/ 19 октября 2008

Как насчет того, чтобы клиент не обновлял свою локальную копию, пока сервер не подтвердит обновление счетчика сервера.

Итак:

Клиент рассчитывает следующее значение Клиент отправляет следующее значение на сервер Сервер проверяет правильность следующего значения (еще не замечено) Счетчик обновлений сервера до следующего значения (при необходимости) Сервер уведомляет клиента о получении следующего значения Клиент обновляет локальный счетчик до следующего значения

Если сервер не получает обновление клиента, клиент просто отправляет вычисленное следующее значение. Если клиент не получит подтверждение следующего значения, он повторно отправит следующее значение, но сервер, уже увидевший его, не обновляет, а просто подтверждает. В конце концов, клиент видит сообщение сервера и продолжает. Это относится к случаю потерянных сообщений.

Если вы обеспокоены коррупцией, рассчитайте контрольную сумму в сообщении и отправьте ее. Пересчитайте контрольную сумму при получении и сравните ее с отправленной. Как правило, сетевой стек делает это за вас, поэтому я бы не стал сильно беспокоиться об этом, если вы не используете свой собственный протокол.

1 голос
/ 19 октября 2008

Простой ответ заключается в том, чтобы сделать одного из клиентов или серверов владельцем ресурса, вместо того, чтобы оба иметь собственную копию ресурса.

Если вы используете надежный протокол, такой как TCP, вам не нужно беспокоиться о том, что сообщение не будет доставлено клиенту.

Хорошая вещь, которой нужно следовать при выполнении клиент-серверной работы, - сделать все операции идемпотентными. То есть каждая функция может быть вызвана один или несколько раз без каких-либо побочных эффектов. В этом случае у вас вообще не будет функции увеличения. Вместо этого у вас есть функция set.

...