Delen via


Betrouwbare WebSocket maken met subprotocol

Wanneer WebSocket-clientverbindingen worden verbroken vanwege onregelmatige netwerkproblemen, kunnen berichten verloren gaan. In een pub-/subsysteem worden uitgevers losgekoppeld van abonnees, zodat uitgevers mogelijk geen verbroken verbinding of verlies van berichten van abonnees detecteren. Het is van cruciaal belang voor clients om onregelmatige netwerkproblemen te overwinnen en betrouwbare berichtbezorging te onderhouden. Hiervoor kunt u een betrouwbare WebSocket-client maken met behulp van betrouwbare Azure Web PubSub-subprotocollen.

Reliable Protocol

De Web PubSub-service ondersteunt twee betrouwbare subprotocollen json.reliable.webpubsub.azure.v1 en protobuf.reliable.webpubsub.azure.v1. Clients moeten de uitgevers-, abonnee- en herstelonderdelen van het subprotocol volgen om betrouwbaarheid te bereiken. Als het subprotocol niet goed kan worden geïmplementeerd, kan dit ertoe leiden dat de berichtbezorging niet werkt zoals verwacht of dat de service de client beëindigt vanwege protocolschendingen.

De eenvoudige manier: client-SDK gebruiken

De eenvoudigste manier om een betrouwbare client te maken, is door client-SDK te gebruiken. Client-SDK implementeert web pubsub-clientspecificatie en gebruikt json.reliable.webpubsub.azure.v1 standaard. Raadpleeg Publiceren/abonneren tussen clients voor snel starten.

De harde manier - met de hand implementeren

In de volgende zelfstudie wordt u begeleid bij het belangrijke onderdeel van het implementeren van de Web PubSub-clientspecificatie. Deze handleiding is niet bedoeld voor mensen die snel aan de slag willen, maar die het principe van het bereiken van betrouwbaarheid willen weten. Gebruik de client-SDK voor snel starten.

Initialisatie

Als u betrouwbare subprotocollen wilt gebruiken, moet u het subprotocol instellen bij het maken van WebSocket-verbindingen. In JavaScript kunt u de volgende code gebruiken:

  • Gebruik een betrouwbaar Json-subprotocol:

    var pubsub = new WebSocket(
      "wss://test.webpubsub.azure.com/client/hubs/hub1",
      "json.reliable.webpubsub.azure.v1"
    );
    
  • Gebruik Protobuf reliable subprotocol:

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

Herstel van verbinding

Verbindingsherstel is de basis van het bereiken van betrouwbaarheid en moet worden geïmplementeerd bij het gebruik van de json.reliable.webpubsub.azure.v1 en protobuf.reliable.webpubsub.azure.v1 protocollen.

WebSocket-verbindingen zijn afhankelijk van TCP. Wanneer de verbinding niet wordt verbroken, zijn berichten verliesloos en bezorgd in volgorde. Om te voorkomen dat berichten verloren gaan via verbroken verbindingen, behoudt de Web PubSub-service de statusgegevens van de verbinding, inclusief groeps- en berichtgegevens. Deze informatie wordt gebruikt om de client te herstellen bij herstel van de verbinding

Wanneer de client opnieuw verbinding maakt met de service met behulp van betrouwbare subprotocollen, ontvangt de client een Connected bericht met de connectionId en reconnectionToken. Hiermee connectionId wordt de sessie van de verbinding in de service geïdentificeerd.

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

Zodra de WebSocket-verbinding is gestopt, moet de client proberen opnieuw verbinding te maken met hetzelfde connectionId om dezelfde sessie te herstellen. Clients hoeven niet met de server te onderhandelen en de access_token. Om de verbinding te herstellen, moet de client een WebSocket-verbindingsaanvraag rechtstreeks naar de service maken met de servicehostnaam, connection_iden reconnection_token:

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

Herstel van de verbinding kan mislukken als het netwerkprobleem nog niet is hersteld. De client moet opnieuw proberen opnieuw verbinding te maken totdat:

  1. De WebSocket-verbinding wordt gesloten met statuscode 1008. De statuscode betekent dat de connectionId is verwijderd uit de service.
  2. Er blijft een herstelfout optreden gedurende meer dan 1 minuut.

Publisher

Clients die gebeurtenissen verzenden naar gebeurtenis-handlers of berichten publiceren naar andere clients, worden uitgevers genoemd. Uitgevers moeten in het bericht worden ingesteld ackId om een bevestiging te ontvangen van de Web PubSub-service die het bericht heeft gepubliceerd of niet.

De ackId id van het bericht is, elk nieuw bericht moet een unieke id gebruiken. Het origineel ackId moet worden gebruikt bij het opnieuw verzenden van een bericht.

Een voorbeeldgroep verzendt een bericht:

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

Een voorbeeld van een ack-antwoord:

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

Wanneer de Web PubSub-service een ack-antwoord retourneert, success: trueis het bericht verwerkt door de service en kan de client verwachten dat het bericht aan alle abonnees wordt bezorgd.

Wanneer de service een tijdelijke interne fout ondervindt en het bericht niet kan worden verzonden naar abonnee, ontvangt de uitgever een ack met success: false. De uitgever moet de fout lezen om te bepalen of het bericht al dan niet opnieuw moet worden verzonden. Als het bericht opnieuw wordt verzonden, moet hetzelfde ackId worden gebruikt.

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

Berichtfout

Als het ack-antwoord van de service verloren gaat omdat de WebSocket-verbinding is verbroken, moet de uitgever het bericht opnieuw verzenden met hetzelfde ackId na herstel. Wanneer het bericht eerder door de service is verwerkt, wordt er een ack met een Duplicate fout verzonden. De uitgever moet stoppen met het opnieuw verzenden van dit bericht.

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

Bericht gedupliceerd

Abonnee

Clients die berichten ontvangen van gebeurtenis-handlers of uitgevers, worden abonnees genoemd. Wanneer verbindingen worden afgebroken vanwege netwerkproblemen, weet de Web PubSub-service niet hoeveel berichten er naar abonnees zijn verzonden. Om te bepalen welk laatste bericht de abonnee heeft ontvangen, verzendt de service een gegevensbericht met een sequenceId. De abonnee reageert met een reeks-ack-bericht:

Een voorbeeldreeks ack:

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

Het sequenceId is een uint64 incrementeel getal in een sessie met de verbindings-id. Abonnees moeten het grootste sequenceId opnemen dat het heeft ontvangen, alleen berichten accepteren met een grotere sequenceIden berichten verwijderen met een kleiner of gelijk.sequenceId De abonnee moet met het grootste sequenceId aantal geregistreerde berichten worden overgeslagen, zodat de service opnieuw verzendende berichten kan overslaan die abonnees al hebben ontvangen. Als de abonnee bijvoorbeeld reageert met een sequenceAck met sequenceId: 5, wordt de service alleen berichten met een sequenceId groter dan 5 opnieuw verzonden.

Alle berichten worden bezorgd bij abonnees totdat de WebSocket-verbinding wordt beëindigd. Hiermee sequenceIdkan de service weten hoeveel berichten abonnees hebben ontvangen via WebSocket-verbindingen in een sessie. Nadat een WebSocket-verbinding is afgevallen, worden berichten die niet door de abonnee zijn bevestigd, opnieuw verzonden. De service slaat een beperkt aantal niet-bekende berichten op. Wanneer het aantal berichten de limiet overschrijdt, wordt de WebSocket-verbinding gesloten en wordt de sessie verwijderd. Abonnees moeten dus zo sequenceId snel mogelijk afhalen.