How to receive service disruption callbacks and recover each affected service after an internal platform failure.

Cette rubrique comprend les sections suivantes :


Vue d'ensemble

La plateforme Vonage Video surveille en permanence tous les services en cours d'exécution. Lorsqu'une défaillance interne affecte un service — par exemple, un plantage du serveur multimédia, une défaillance de l'archiveur, la mise hors service d'un nœud de diffusion, un problème de passerelle SIP ou une défaillance du moteur de sous-titrage —, le système de surveillance de la plateforme détecte la défaillance, met à jour l'état du service et envoie immédiatement une notification de rappel vers votre terminal enregistré.

Ce guide explique quels callbacks chaque service émet en cas de perturbation, à quoi ressemblent les données transmises et comment rétablir le fonctionnement de chaque service par programmation.

Les perturbations de service peuvent affecter l'un des services Vonage Video suivants :

Service What is disrupted Primary callback mechanism
Sessions Media Router crashes; participant connections and streams are terminated Server-side session monitoring webhook + client SDK events
Archives (Recordings) Archiver process crashes; the recording is terminated abnormally Archive status webhook ("status": "failed")
Broadcasts Broadcast node fails; the HLS/RTMP stream is terminated Broadcast status webhook ("status": "failed")
SIP Calls SIP gateway fails; the call leg is dropped Session monitoring webhook callDestroyed
Captions Captions engine fails; live transcription stops Captions status webhook ("status": "failed")

Dans tous les cas, le reason Le champ dans la charge utile du rappel est en général réglé sur "Internal server failure". D'autres valeurs de motif peuvent apparaître en fonction de la nature de la défaillance ; votre code de récupération doit donc traiter toute interruption inattendue (non provoquée par vos propres appels d'API) comme une perturbation potentielle.

Remarque : La plateforme envoie également des alertes avant interruption en cas de rotation des serveurs (reason: "serverRotation") via le sessionNotification événement. Voir Rotation des serveurs et migration des sessions pour plus de détails sur ce scénario précis.


Conditions préalables

Pour recevoir des rappels en cas d'incident côté serveur, vous devez enregistrer un Rappel de surveillance de session URL pour votre projet. Voir Suivi de la session pour les instructions d'installation.

Pour les rappels d'état concernant les archives, les diffusions et les sous-titres, configurez l'URL de rappel d'état correspondante dans votre Tableau de bord du projet Video API Vonage.


Interruption de la session

Lorsque le Media Router hébergeant une session plante, la session est interrompue et la plateforme envoie un sessionDestroyed événement vers votre point de terminaison de surveillance de session.

Contenu de la fonction de rappel

sessionDestroyed

{
  "sessionId": "2_MX4xMzExMjU3MX5-MTQ3MDI1NzY3OTkxOH45QXRr",
  "projectId": "123456",
  "event": "sessionDestroyed",
  "reason": "forceDisconnected",
  "timestamp": 1718000050000
}

Événements du Client SDK

Parallèlement aux webhooks côté serveur, les clients reçoivent des événements liés au cycle de vie via le SDK :

session.on('sessionReconnecting', () => {
  // Platform is attempting automatic reconnection via session migration
  showReconnectingBanner();
});

session.on('sessionReconnected', () => {
  // Automatic recovery succeeded — no further action needed
  hideReconnectingBanner();
});

session.on('sessionDisconnected', (event) => {
  // Automatic recovery failed or is not enabled
  if (event.reason === 'networkDisconnected' || event.reason === 'networkTimedout') {
    promptUserToRejoin();
  }
});

publisher.on('streamDestroyed', (event) => {
  if (event.reason === 'networkDisconnected') {
    event.preventDefault(); // Keep the publisher element in the DOM
    retryPublish();
  }
});

Pour les SDK natifs, utilisez les méthodes de délégué équivalentes :

  • iOS : OTSessionDelegate.sessionDidBeginReconnecting(_:) / sessionDidReconnect(_:) / sessionDidDisconnect(_:)
  • Android : Session.SessionListener.onReconnecting() / onReconnected() / onDisconnected()

Rétablissement

Quand sessionDisconnected incendies avec reason: "forceDisconnected" (ou après sessionReconnecting délays d'expiration) :

  1. Créez une nouvelle session via l'API REST ou un SDK serveur.
  2. Émettre de nouveaux jetons pour tous les participants.
  3. Invitez vos clients à se reconnecter — via votre propre canal de notification, par notification push ou par message intégré à l'application.
// Server-side — handle sessionDestroyed with reason "forceDisconnected"
app.post('/callbacks/vonage/session', (req, res) => {
  const { event, reason, sessionId } = req.body;

  if (event === 'sessionDestroyed' && reason === 'forceDisconnected') {
    createNewSessionAndNotifyClients(sessionId);
  }

  res.sendStatus(200);
});

Conseil : Si Migration de la session est activée, la plateforme peut rétablir automatiquement la session. Dans ce cas, sessionReconnected se lance automatiquement sur le client et ne nécessite aucune reconnexion manuelle.


Problème d'archivage (enregistrement)

Lorsqu'un processus d'archivage se bloque en cours d'enregistrement, le système de surveillance de la plateforme détecte la défaillance et marque l'archive comme "failed", et envoie une réponse de statut à l'URL de statut de votre archive enregistrée.

Contenu de la fonction de rappel

{
  "id": "b40ef09b-3811-4726-b508-e41a0f96c68f",
  "event": "archive",
  "status": "failed",
  "reason": "Internal server failure",
  "sessionId": "2_MX4xMzExMjU3MX5-MTQ3MDI1NzY3OTkxOH45QXRr",
  "projectId": "123456",
  "name": "My Recording",
  "createdAt": 1718000000000,
  "duration": 0,
  "outputMode": "composed",
  "hasVideo": true,
  "hasAudio": true
}

Champs clés :

Field Value on disruption
status "failed"
reason "Internal server failure"
duration May be 0 if the failure occurred before the first segment was written

Rétablissement

app.post('/callbacks/vonage/archive', (req, res) => {
  const { status, reason, sessionId } = req.body;

  if (status === 'failed' && reason === 'Internal server failure') {
    // Start a new archive for the same session
    opentok.startArchive(sessionId, { name: 'Resumed recording' }, (err, archive) => {
      if (err) console.error('Failed to restart archive:', err);
      else console.log('New archive started:', archive.id);
    });
  }

  res.sendStatus(200);
});

Remarque : Vérifiez toujours qu'il reste des participants actifs dans la session avant de relancer l' archivage. Le lancement d'un archivage sur une session vide entraînera une erreur.


Interruption de la diffusion

Lorsqu'un nœud de diffusion tombe en panne, le flux HLS ou RTMP est interrompu et la diffusion est marquée comme "failed". Une réponse de statut est envoyée à votre URL de statut de diffusion.

Contenu de la fonction de rappel

{
  "id": "1748b707-0a81-464c-9759-c46ad10d3734",
  "sessionId": "2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4",
  "applicationId": 100,
  "createdAt": 1437676551000,
  "updatedAt": 1437676551000,
  "event": "broadcast",
  "group": "status",
  "resolution": "640x480",
  "streamMode": "auto",
  "streams": [],
  "broadcastUrls": {
    "hls": "http://server/fakepath/playlist.m3u8",
    "hlsStatus": "error",
    "rtmp": {
      "foo": {
        "serverUrl": "rtmps://myfooserver:443/myfooapp",
        "streamName": "myfoostream",
        "status": "error"
      },
      "bar": {
        "serverUrl": "rtmp://mybarserver:443/mybarapp",
        "streamName": "mybarstream",
        "status": "error"
      }
    }
  },
  "settings": {
    "hls": {
      "dvr": false,
      "lowLatency": false
    }
  },
  "status": "failed",
  "reason": "internal server failure"
}

Rétablissement

  1. Recevez le "failed" rappel d'état.
  2. Attendez que les clients se soient reconnectés à la session (surveillez l'événement connectionCreated événements, ou les participants à un sondage).
  3. Lancer une nouvelle diffusion :
app.post('/callbacks/vonage/broadcast', (req, res) => {
  const { status, reason, sessionId } = req.body;

  if (status === 'failed' && reason === 'Internal server failure') {
    waitForParticipants(sessionId).then(() => {
      opentok.startBroadcast(sessionId, broadcastOptions, (err, broadcast) => {
        if (err) console.error('Failed to restart broadcast:', err);
        else notifyViewersOfNewStreamUrl(broadcast.broadcastUrls);
      });
    });
  }

  res.sendStatus(200);
});

Important : L'URL HLS change à chaque nouvelle diffusion. Veillez à mettre à jour tous les lecteurs ou systèmes en aval qui exploitent ce flux avec la nouvelle URL.


Perturbation des appels SIP

Lorsqu'une défaillance de la passerelle SIP entraîne la coupure d'une branche d'appel active, la connexion SIP est interrompue et la plateforme envoie callDestroyed vers votre point de terminaison de surveillance de session avec reason_message: "Unexpected Clearing".

Contenu de la fonction de rappel

{
  "sessionId": "2_MX4xMzExMjU3MX5-MTQ3MDI1NzY3OTkxOH45QXRr",
  "applicationId": "123456",
  "event": "callDestroyed",
  "reason_code": "703",
  "reason_message": "Unexpected Clearing",
  "timestamp": 1718000050000,
  "call": {
    "id": "<conference-id>",
    "connectionId": "<sip-ot-connection-id>",
    "createdAt": 1470257688143
  }
}

Rétablissement

app.post('/callbacks/vonage/session', (req, res) => {
  const { event, reason_message, call, sessionId } = req.body;

  if (event === 'callDestroyed' && reason_message === 'Unexpected Clearing') {
    // Re-initiate the SIP call
    const sipUri = getSipUriForCall(call.id);
    opentok.dial(sessionId, token, sipUri, sipOptions, (err, newCall) => {
      if (err) console.error('SIP redial failed:', err);
      else console.log('SIP call re-established:', newCall.id);
    });
  }

  res.sendStatus(200);
});

Perturbation des sous-titres

En cas de défaillance du moteur de sous-titrage, la transcription en direct s'interrompt et la session de sous-titrage est marquée comme "failed". Une notification de statut est envoyée à l'URL de statut de vos sous-titres.

Contenu de la fonction de rappel

{
  "captionsId": "<captionsId>",
  "projectId": "<applicationId>",
  "sessionId": "<sessionId>",
  "status": "failed",
  "createdAt": 1651253477,
  "updatedAt": 1651253837,
  "duration": 360,
  "languageCode": "en-US",
  "reason": "Internal server failure",
  "provider": "aws-transcribe",
  "event": "sessionStatus"
}

Rétablissement

app.post('/callbacks/vonage/captions', (req, res) => {
  const { status, reason, sessionId } = req.body;

  if (status === 'failed' && reason === 'Internal server failure') {
    // Restart captions for the session
    fetch(`https://video.api.vonage.com/v2/project/${PROJECT_ID}/captions`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${jwt}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ sessionId, token: generateToken(sessionId) })
    })
    .then(res => res.json())
    .then(data => console.log('Captions restarted:', data.captionsId))
    .catch(err => console.error('Failed to restart captions:', err));
  }

  res.sendStatus(200);
});

Meilleures pratiques

  • Vérifiez toujours le reason champ, mais ne vous fiez pas uniquement à cela. Bien que les perturbations entraînent généralement "Internal server failure", votre logique de récupération doit gérer toute situation imprévue "failed" statut ou <something>Destroyed cet événement comme une perturbation potentielle de la plateforme.
  • Implémenter des gestionnaires de récupération idempotents. Les rappels peuvent être déclenchés plusieurs fois. Utilisez l'identifiant de la ressource (archive.id, captionsId, session.id) pour effectuer la déduplication.
  • Utilisez les avertissements de pré-rotation. Les sessionNotification événement (avec remainingTime: 3600 ou 14400) vous informe à l'avance des rotations prévues. Utilisez-le pour arrêter proprement les archives, les diffusions et les sous-titres avant la rotation, afin d'éviter un arrêt brutal "forceDisconnected" résiliation.
  • Enregistrer tous les incidents avec leur charge utile complète en vue d'une analyse a posteriori. Le timestamp Ce champ constitue votre référence pour le calcul de la durée de l'impact.
  • Pour les sessions, privilégiez la migration de session. L'activation de la migration de session réduit considérablement l'ampleur des pannes du Media Router en redirigeant de manière transparente les clients vers un serveur opérationnel. Voir Rotation des serveurs et migration des sessions.
  • Configurer des alertes sur "Internal server failure" rappels. Une forte hausse de Internal server failure La survenue d'événements sur plusieurs sessions constitue un signe précoce d'un incident plus vaste affectant la plateforme.

Voir aussi