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) :
- Créez une nouvelle session via l'API REST ou un SDK serveur.
- Émettre de nouveaux jetons pour tous les participants.
- 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
- Recevez le
"failed"rappel d'état. - Attendez que les clients se soient reconnectés à la session (surveillez l'événement
connectionCreatedévénements ou participants aux scrutins). - 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
reasonchamp, 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>Destroyedcet é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 (avecremainingTime: 3600ou14400) 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
timestampCe 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 deInternal server failureLa survenue d'événements sur plusieurs sessions constitue un signe précoce d'un incident plus vaste affectant la plateforme.
Ressources connexes
- Suivi de la session
- Rotation des serveurs et migration des sessions
- Guide d'archivage
- Guide des programmes
- Guide d'interconnexion SIP
- Guide sur les sous-titres en direct