Rappels en cas de perturbation du service

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 au niveau de la 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 chaque service par programmation.

Vue d'ensemble

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

Service Qu'est-ce qui est perturbé ? Mécanisme de rappel principal
Sessions Le routeur multimédia plante ; les connexions des participants et les flux sont interrompus Webhook de surveillance des sessions côté serveur + événements du Client SDK
Archives (Enregistrements) Le processus d'archivage plante ; l'enregistrement s'interrompt de manière anormale Webhook d'état des archives ("status": "failed")
Émissions Défaillance du nœud de diffusion ; le flux HLS/RTMP est interrompu Webhook d'état de diffusion ("status": "failed")
Appels SIP La passerelle SIP tombe en panne ; la liaison d'appel est interrompue Webhook de surveillance des sessions callDestroyed
Légendes Le moteur de sous-titrage tombe en panne ; la transcription en direct s'interrompt Webhook d'état des sous-titres ("status": "failed")

Dans tous les cas, le reason Le champ dans la charge utile de la fonction de rappel est en général fixé à "forceDisconnected". 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 considérer toute interruption inattendue (non provoquée par vos propres appels d'API) comme une perturbation potentielle.

Remarque : La plateforme envoie également alertes préalables à une perturbation pour les rotations de serveurs (reason: "serverRotation") via le sessionNotification événement. Voir Rotation des serveurs et migration des sessions pour plus de détails sur ce cas précis.

Conditions préalables

Pour recevoir des rappels en cas d'incident côté serveur, vous devez enregistrer un URL de rappel pour la surveillance de session 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.

Données de rappel

{
  "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 si cette option est activée, la plateforme peut rétablir automatiquement la session. Dans ce cas, sessionReconnected se déclenche côté client et ne nécessite aucune reconnexion manuelle.


Problème d'archivage (enregistrement)

Lorsqu'un processus d'archivage plante 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 d'état à l'URL d'état de l'archive que vous avez 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 :

Champ d'application La valeur de la disruption
status "failed"
reason "Internal server failure"
duration Peut-être 0 si la défaillance s'est produite avant l'écriture du premier segment

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 participants aux scrutins).
  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 la nouvelle URL sur tous les lecteurs ou systèmes en aval qui exploitent ce flux.


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 à l'aide de reason_message: "Unexpected Clearing". Les données d'une connexion SIP contiennent généralement un sip identifiant permettant de le distinguer des connexions des participants habituels.

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

Identifier les connexions SIP en les analysant connection.data, puis recomposez le numéro :

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

  if (event === 'callDestroyed' && reason_message === 'Unexpected Clearing') {
    let connData = {};
    try { connData = JSON.parse(connection.data); } catch (_) {}

    if (connData.sip) {
      // Re-initiate the SIP call
      const sipUri = getSipUriForConnection(connection.id);
      opentok.dial(sessionId, token, sipUri, sipOptions, (err, call) => {
        if (err) console.error('SIP redial failed:', err);
        else console.log('SIP call re-established:', call.id);
      });
    }
  }

  res.sendStatus(200);
});

Perturbation des sous-titres

En cas de défaillance du moteur de sous-titrage, la transcription en direct s'arrête 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 s’accompagnent généralement de "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 callbacks 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.

Ressources connexes