Question

Disons que j'ai une variable de compteur côté client. Lorsque j'envoie une requête au serveur, j'envoie la valeur de cette variable, puis l'incrémente de un (pour la requête suivante adressée au serveur). Le serveur garde la trace de ce compteur indépendamment et vérifie que le compte envoyé par le client est égal à 1 de plus que sa propre copie (côté serveur) du compte. Tout va bien, mais considérons la situation suivante:

  1. Le client envoie par exemple 23 au serveur.
  2. Le serveur en reçoit 23, le valide et incrémente son propre compteur à 23.
  3. Le serveur renvoie le code Tout-Okay au client

-BUT -

Au cours du trajet entre le serveur et le client, le code de retour est corrompu. Le client pense donc que le serveur n’a pas mis à jour son compteur et laisse donc le compteur côté client à 23. À partir de ce moment, le client et le serveur ne sont plus synchronisés.

Quelqu'un connaît-il des systèmes robustes qui fonctionneraient face à de telles erreurs / corruption?

Merci,
Cameron

Était-ce utile?

La solution

Au lieu d'utiliser un compteur à augmentation linéaire, vous pouvez utiliser une "nonce" aléatoire. valeur d'un bon 64 bits d'entropie ou plus. Lorsque le serveur reçoit une demande du client, il vérifie si le nonce correspond au dernier message envoyé au client. Si tel est le cas, la demande est traitée et le serveur génère une nouvelle valeur de nonce aléatoire à envoyer dans la réponse.

Le serveur peut conserver les deux dernières valeurs nonce à envoyer au client. Si le client envoie l'ancienne valeur, le serveur suppose que le message le plus récent envoyé au client a peut-être été perdu.

La méthode ci-dessus suppose que votre objectif est d'empêcher deux clients différents d'utiliser les mêmes informations d'identification pour communiquer avec le serveur. L’avantage de l’utilisation de la méthode nonce est que la prochaine valeur est difficilement prévisible.

Autres conseils

La réponse simple est de faire de l’un des clients, client ou serveur, le propriétaire de la ressource, au lieu de créer sa propre copie de la ressource.

Si vous utilisez un protocole fiable tel que TCP, vous n'avez pas à vous soucier du message qui ne parvient pas au client.

Une bonne chose à suivre lorsque vous effectuez un travail client / serveur est de rendre toutes les opérations idempotentes. C'est-à-dire que chaque fonction peut être appelée une ou plusieurs fois sans aucun effet secondaire. Dans ce cas, vous n’auriez aucune fonction d’incrémentation. Au lieu de cela, vous auriez une fonction 'set'.

Pourquoi ne pas demander au client de mettre à jour sa copie locale tant que le serveur n’a pas accusé réception de la mise à jour du compteur du serveur.

Donc:

Le client calcule la valeur suivante Le client envoie la valeur suivante au serveur Le serveur vérifie que la valeur suivante est valide (pas encore vue) Le serveur met à jour le compteur à la valeur suivante (si nécessaire) Le serveur informe le client que la prochaine valeur a été reçue Le client met à jour le compteur local à la valeur suivante

Si le serveur ne reçoit pas la mise à jour du client, le client renvoie simplement la valeur suivante calculée. Si le client ne reçoit pas la confirmation de valeur suivante, il renverra la valeur suivante, mais le serveur l'ayant déjà vue ne se met pas à jour, mais acquitte simplement. Finalement, le client voit le message du serveur et continue. Cela couvre le cas des messages perdus.

Si la corruption vous préoccupe, calculez une somme de contrôle sur le message et envoyez-la également. Recalculez la somme de contrôle à la réception et comparez-la à celle envoyée. En général, la pile réseau le fait pour vous, donc je ne m'inquiéterais pas trop si vous n'exécutez pas votre propre protocole.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top