Créer un WebSocket fiable avec sous-protocole

Lorsque les connexions clientes Websocket sont supprimées en raison de problèmes réseau intermittents, les messages peuvent être perdus. Dans un système pub/sous-système, les éditeurs sont dissociés des abonnés. Les éditeurs peuvent donc ne pas détecter la perte de connexion ou de message supprimée d’un abonné. Il est essentiel pour les clients de surmonter les problèmes réseau intermittents et de maintenir une remise de messages fiable. Pour ce faire, vous pouvez créer un client Websocket fiable à l’aide de sous-protocoles Azure Web PubSub fiables.

Protocole fiable

Le service Web PubSub prend en charge deux sous-protocole json.reliable.webpubsub.azure.v1 fiables et protobuf.reliable.webpubsub.azure.v1. Les clients doivent suivre l’éditeur, l’abonné et les parties de récupération du sous-protocole pour obtenir la fiabilité. L’échec de l’implémentation correcte du sous-protocole peut entraîner la remise des messages qui ne fonctionne pas comme prévu ou si le service met fin au client en raison de violations de protocole.

Easy Way - Utiliser le Kit de développement logiciel (SDK) client

La façon la plus simple de créer un client fiable consiste à utiliser le Kit de développement logiciel (SDK) client. Le Kit de développement logiciel (SDK) client implémente la spécification du client Web PubSub et utilise json.reliable.webpubsub.azure.v1 par défaut. Reportez-vous à Publier/s’abonner parmi les clients pour un démarrage rapide.

The Hard Way - Implémenter à la main

Le tutoriel suivant vous guide tout au long de la partie importante de l’implémentation de la spécification du client Web PubSub. Ce guide n’est pas destiné aux personnes qui cherchent un démarrage rapide, mais qui veulent connaître le principe d’atteindre la fiabilité. Pour démarrer rapidement, utilisez le Kit de développement logiciel (SDK) client.

Initialisation

Pour utiliser des sous-protocole fiables, vous devez définir le sous-protocole lors de la construction de connexions Websocket. En JavaScript, vous pouvez utiliser le code suivant :

  • Utilisez le sous-protocole fiable Json :

    var pubsub = new WebSocket(
      "wss://test.webpubsub.azure.com/client/hubs/hub1",
      "json.reliable.webpubsub.azure.v1"
    );
    
  • Utilisez le sous-protocole Protobuf fiable :

    var pubsub = new WebSocket(
      "wss://test.webpubsub.azure.com/client/hubs/hub1",
      "protobuf.reliable.webpubsub.azure.v1"
    );
    

Récupération de la connexion

la récupération d’Connecter ion est la base de la fiabilité et doit être implémentée lors de l’utilisation des protocoles et protobuf.reliable.webpubsub.azure.v1 des json.reliable.webpubsub.azure.v1 protocoles.

Les connexions Websocket s’appuient sur TCP. Lorsque la connexion ne supprime pas, les messages sont sans perte et remis dans l’ordre. Pour éviter la perte de messages sur les connexions supprimées, le service Web PubSub conserve les informations d’état de connexion, notamment les informations de groupe et de message. Ces informations sont utilisées pour restaurer le client lors de la récupération de connexion

Lorsque le client se reconnecte au service à l’aide de sous-protocoles fiables, le client reçoit un Connected message contenant le connectionId et reconnectionToken. Identifie connectionId la session de la connexion dans le service.

{
  "type": "system",
  "event": "connected",
  "connectionId": "<connection_id>",
  "reconnectionToken": "<reconnection_token>"
}

Une fois la connexion WebSocket abandonnée, le client doit essayer de se reconnecter avec la même connectionId session pour restaurer la même session. Les clients n’ont pas besoin de négocier avec le serveur et d’obtenir le access_token. Au lieu de cela, pour récupérer la connexion, le client doit effectuer une demande de connexion WebSocket directement au service avec le nom d’hôte du service, connection_idet reconnection_token:

wss://<service-endpoint>/client/hubs/<hub>?awps_connection_id=<connection_id>&awps_reconnection_token=<reconnection_token>

la récupération de Connecter ion peut échouer si le problème réseau n’a pas encore été récupéré. Le client doit continuer à réessayer de se reconnecter jusqu’à ce que :

  1. La connexion Websocket est fermée avec le code d’état 1008. Le code d’état signifie que le connectionId a été supprimé du service.
  2. Une défaillance de récupération continue de se produire pendant plus de 1 minute.

Serveur de publication

Les clients qui envoient des événements à des gestionnaires d’événements ou publient des messages sur d’autres clients sont appelés éditeurs. Les éditeurs doivent définir ackId dans le message pour recevoir un accusé de réception du service Web PubSub qui a publié le message a réussi ou non.

Il ackId s’agit de l’identificateur du message, chaque nouveau message doit utiliser un ID unique. L’original ackId doit être utilisé lors du renvoi d’un message.

Un exemple de message envoyé à un groupe :

{
  "type": "sendToGroup",
  "group": "group1",
  "dataType": "text",
  "data": "text data",
  "ackId": 1
}

Un exemple de réponse d’accusé de réception :

{
  "type": "ack",
  "ackId": 1,
  "success": true
}

Lorsque le service Web PubSub retourne une réponse d’erreur avec success: true, le message a été traité par le service et le client peut s’attendre à ce que le message soit remis à tous les abonnés.

Lorsque le service rencontre une erreur interne temporaire et que le message ne peut pas être envoyé à l’abonné, l’éditeur reçoit une erreur success: false. L’éditeur doit lire l’erreur pour déterminer s’il faut renvoyer ou non le message. Si le message est renvoyé, le même ackId doit être utilisé.

{
  "type": "ack",
  "ackId": 1,
  "success": false,
  "error": {
    "name": "InternalServerError",
    "message": "Internal server error"
  }
}

Message Failure

Si la réponse ack du service est perdue, car la connexion WebSocket a été supprimée, l’éditeur doit renvoyer le message avec le même ackId message après la récupération. Lorsque le message a été précédemment traité par le service, il envoie une erreur contenant une Duplicate erreur. L’éditeur doit cesser de renvoyer ce message.

{
  "type": "ack",
  "ackId": 1,
  "success": false,
  "error": {
    "name": "Duplicate",
    "message": "Message with ack-id: 1 has been processed"
  }
}

Message duplicated

Abonné

Les clients qui reçoivent des messages provenant de gestionnaires d’événements ou d’éditeurs sont appelés abonnés. Lorsque les connexions tombent en raison de problèmes réseau, le service Web PubSub ne sait pas combien de messages ont été envoyés aux abonnés. Pour déterminer le dernier message reçu par l’abonné, le service envoie un message de données contenant un sequenceId. L’abonné répond avec un message de séquence :

Exemple d’accusé de réception de séquence :

{
  "type": "sequenceAck",
  "sequenceId": 1
}

Il sequenceId s’agit d’un numéro incrémentiel uint64 dans une session d’ID de connexion. Les abonnés doivent enregistrer le plus grand sequenceId qu’il a reçu, accepter uniquement les messages avec une plus grande sequenceIdtaille et supprimer des messages avec un plus petit ou égal sequenceId. L’abonné doit avoir le plus grand sequenceId qu’il a enregistré, afin que le service puisse ignorer les messages redéliver que les abonnés ont déjà reçus. Par exemple, si l’abonné répond avec un sequenceAck avec sequenceId: 5, le service renvoie uniquement des messages dont sequenceId la taille est supérieure à 5.

Tous les messages sont remis aux abonnés dans l’ordre jusqu’à ce que la connexion WebSocket tombe. Avec sequenceId, le service peut savoir combien d’abonnés ont reçus sur les connexions WebSocket dans une session. Une fois qu’une connexion WebSocket est abandonnée, le service redélivera les messages non reconnus par l’abonné. Le service stocke un nombre limité de messages non connus. Lorsque le nombre de messages dépasse la limite, le service ferme la connexion WebSocket et supprime la session. Par conséquent, les abonnés doivent s’en sequenceId servir dès que possible.