How to receive service disruption callbacks and recover each affected service after an internal platform failure.
Este tema incluye las siguientes secciones:
- Visión general
- Requisitos previos
- Interrupción de la sesión
- Interrupción del archivo (grabación)
- Interrupción de la emisión
- Interrupción de una llamada SIP
- Interrupción de los subtítulos
- Buenas prácticas
Visión general
La plataforma Vonage Video supervisa continuamente todos los servicios en ejecución. Cuando un fallo interno afecta a un servicio —como un fallo del servidor multimedia, un fallo del archivador, la caída de un nodo de difusión, un problema con la pasarela SIP o un fallo del motor de subtítulos—, el sistema de supervisión de la plataforma detecta el fallo, actualiza el estado del servicio y envía inmediatamente una notificación de devolución de llamada a tu terminal registrado.
Esta guía explica qué funciones de devolución de llamada emite cada servicio en caso de interrupción, cómo son las cargas útiles y cómo recuperar cada servicio mediante programación.
Las interrupciones del servicio pueden afectar a cualquiera de los siguientes servicios de Vonage Video:
| 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") |
En todos los casos, el reason El campo en la carga útil de la llamada de retorno es normalmente establecer en
"Internal server failure". Pueden aparecer otros valores de motivo en función de la naturaleza del
error, por lo que tu código de recuperación debería tratar cualquier interrupción inesperada (que no esté provocada por tus propias
llamadas a la API) como una posible interrupción del servicio.
Nota: La plataforma también envía avisos previos a las interrupciones por rotaciones de servidores
(reason: "serverRotation") a través de la sessionNotification evento. Véase
Rotación de servidores y migración de sesiones para obtener más información sobre ese
caso concreto.
Requisitos previos
Para recibir notificaciones de interrupciones del lado del servidor, debes registrar un Llamada de retorno de la supervisión de sesiones URL para tu proyecto. Consulta Control de la sesión para obtener instrucciones de configuración.
Para las notificaciones de estado de archivos, emisiones y subtítulos, configura la URL de notificación de estado correspondiente en tu Panel de control del proyecto de la Video API de Vonage.
Interrupción de la sesión
Cuando el Media Router que aloja una sesión se bloquea, la sesión se cancela y la plataforma envía
un sessionDestroyed evento al punto final de supervisión de tu sesión.
Carga útil de la llamada de retorno
sessionDestroyed
{
"sessionId": "2_MX4xMzExMjU3MX5-MTQ3MDI1NzY3OTkxOH45QXRr",
"projectId": "123456",
"event": "sessionDestroyed",
"reason": "forceDisconnected",
"timestamp": 1718000050000
}
Eventos del Client SDK
Paralelamente a los webhooks del lado del servidor, los clientes reciben eventos del ciclo de vida a través del 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();
}
});
Para los SDK nativos, utiliza los métodos delegados equivalentes:
- iOS:
OTSessionDelegate.sessionDidBeginReconnecting(_:)/sessionDidReconnect(_:)/sessionDidDisconnect(_:) - Android:
Session.SessionListener.onReconnecting()/onReconnected()/onDisconnected()
Recuperación
En sessionDisconnected incendios con reason: "forceDisconnected" (o después de
sessionReconnecting tiempo de espera):
- Crea una nueva sesión a través de la API REST o del SDK del servidor.
- Emitir tokens nuevos para todos los participantes.
- Avisa a los clientes para que vuelvan a conectarse —a través de tu propio canal de notificación, mediante notificaciones push o mediante un mensaje dentro de la aplicación—.
// 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);
});
Consejo: Si Migración de sesiones está activada,
la plataforma puede recuperar la sesión automáticamente. En ese caso sessionReconnected se inicia
en el cliente y no es necesario volver a conectarse manualmente.
Interrupción del archivo (grabación)
Cuando un proceso de archivado se bloquea en mitad de la grabación, el sistema de supervisión de la plataforma detecta el
fallo y marca el archivo como "failed", y envía una notificación de estado a la URL de estado de tu archivo
registrada.
Carga útil de la llamada de retorno
{
"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
}
Campos clave:
| Field | Value on disruption |
|---|---|
status |
"failed" |
reason |
"Internal server failure" |
duration |
May be 0 if the failure occurred before the first segment was written |
Recuperación
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);
});
Nota: Verify siempre que la sesión siga teniendo participantes activos antes de reiniciar el archivo. Iniciar un archivo en una sesión vacía provocará un error.
Interrupción de la emisión
Cuando se produce un fallo en un nodo de retransmisión, la transmisión HLS o RTMP se interrumpe y la retransmisión se marca como
"failed". Se envía una respuesta de estado a tu URL de estado de difusión.
Carga útil de la llamada de retorno
{
"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"
}
Recuperación
- Recibe el
"failed"llamada de retorno de estado. - Espera a que los clientes se hayan vuelto a conectar a la sesión (espera a que se detecte
connectionCreatedeventos, o participantes en las encuestas). - Iniciar una nueva retransmisión:
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);
});
Importante: La URL de HLS cambia con cada nueva emisión. Asegúrate de actualizar cualquier reproductor o sistema posterior que utilice la transmisión con la nueva URL.
Interrupción de una llamada SIP
Cuando un fallo en la pasarela SIP provoca la interrupción de un tramo de llamada activo, la conexión SIP se interrumpe y la
plataforma envía callDestroyed a tu punto final de supervisión de sesiones con
reason_message: "Unexpected Clearing".
Carga útil de la llamada de retorno
{
"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
}
}
Recuperación
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);
});
Interrupción de los subtítulos
Cuando el motor de subtítulos falla, la transcripción en directo se detiene y la sesión de subtítulos se marca como
"failed". Se envía una respuesta de estado a la URL de estado de tus subtítulos.
Carga útil de la llamada de retorno
{
"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"
}
Recuperación
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);
});
Buenas prácticas
- Comprueba siempre el
reasoncampo, pero no te bases exclusivamente en ello. Aunque las interrupciones suelen conllevar"Internal server failure", tu lógica de recuperación debería gestionar cualquier"failed"estado o<something>Destroyedacontecimiento como una posible disrupción de la plataforma. - Implementar controladores de recuperación idempotentes. Las llamadas de retorno pueden recibirse más de una vez. Utiliza
el ID del recurso (
archive.id,captionsId,session.id) para eliminar los duplicados. - Utiliza las advertencias previas a la rotación. En
sessionNotificationevento (conremainingTime: 3600o14400) te avisa con antelación de las rotaciones previstas. Úsalo para detener de forma ordenada los archivos, las emisiones y los subtítulos antes de la rotación, evitando así un"forceDisconnected"rescisión. - Registrar todos los incidentes de interrupción del servicio con toda su carga útil para el análisis posterior al incidente. El
timestampEste campo es el valor de referencia para calcular la duración del impacto. - Para las sesiones, es preferible utilizar la migración de sesiones. La activación de la migración de sesiones reduce drásticamente el alcance de los fallos del Media Router, ya que traslada de forma transparente a los clientes a un servidor en buen estado. Ver Rotación de servidores y migración de sesiones.
- Configura alertas en
"Internal server failure"funciones de devolución de llamada. Un repunte enInternal server failureLa aparición de eventos a lo largo de varias sesiones es un indicio temprano de un incidente más amplio en la plataforma.