How to receive service disruption callbacks and recover each affected service after an internal platform failure.
このトピックには以下のセクションが含まれます:
概要
Vonage Videoプラットフォームは、実行中のすべてのサービスを継続的に監視しています。 メディアサーバーのクラッシュ、アーカイバの障害、放送ノードの ダウン、SIPゲートウェイの問題、キャプションエンジンの障害など、内部的な障害が サービスに影響を及ぼした場合、プラットフォームの監視システムが その障害を検知し、サービスの状態を更新した上で、登録済みのエンドポイントへ 直ちにコールバック通知を送信します。
このガイドでは、各サービスが障害発生時にどのコールバックを発行するか、ペイロードの形式、 および各サービスをプログラム的に復旧する方法について説明します。
サービスの中断は、以下の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") |
いずれの場合も、 reason Callback Payload の field は 通常は に設定する
"Internal server failure". 障害の性質によっては、その他の理由値が表示される場合があるため、
リカバリコードでは、(自身の
API呼び出しに起因しない)予期しない終了をすべて、潜在的な障害として扱う必要があります。
注: また、このプラットフォームでは、サーバーのローテーションに関する障害発生前の警告も送信されます
(reason: "serverRotation") を通じて sessionNotification イベントをご覧ください。参照
サーバーのローテーションとセッションの移行 その
具体的なシナリオに関する詳細については。
前提条件
サーバーサイドの障害コールバックを受信するには、 セッション監視のコールバック URL プロジェクト用です。詳しくは セッション監視 をご覧ください。
アーカイブ、放送、および字幕のステータスに関するコールバックについては、 お使いの Vonage Video API プロジェクトダッシュボード.
セッションの中断
セッションをホストしているメディアルーターがクラッシュすると、そのセッションは破棄され、プラットフォームは
a sessionDestroyed セッション監視エンドポイントへのイベント。
コールバックのペイロード
sessionDestroyed
{
"sessionId": "2_MX4xMzExMjU3MX5-MTQ3MDI1NzY3OTkxOH45QXRr",
"projectId": "123456",
"event": "sessionDestroyed",
"reason": "forceDisconnected",
"timestamp": 1718000050000
}
Client SDK のイベント
サーバーサイドのWebhookと並行して、クライアントは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();
}
});
ネイティブSDKの場合は、対応するデリゲートメソッドを使用してください:
- iOS:
OTSessionDelegate.sessionDidBeginReconnecting(_:)/sessionDidReconnect(_:)/sessionDidDisconnect(_:) - アンドロイドだ:
Session.SessionListener.onReconnecting()/onReconnected()/onDisconnected()
回復
いつ sessionDisconnected ~で燃える reason: "forceDisconnected" (またはその後
sessionReconnecting タイムアウト):
- REST API またはサーバー SDK を使用して、新しいセッションを作成します。
- すべての参加者に新しいトークンを発行する。
- クライアントに再接続するよう通知します。独自のシグナリングチャネル、プッシュ通知、または In-App Messagingなどを通じて行います。
// 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);
});
ヒント もし セッション移行 が有効になっている場合、
プラットフォームがセッションを自動的に復元することがあります。その場合は sessionReconnected クライアント側で
自動的に起動し、手動での再接続は不要です。
アーカイブ(録画)の障害
記録の途中でアーカイバプロセスがクラッシュした場合、プラットフォームの監視システムがその
障害を検出し、アーカイブを "failed", 登録済みのアーカイブのステータスURLにステータスコールバックを送信します
。
コールバックのペイロード
{
"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
}
主要な分野:
| Field | Value on disruption |
|---|---|
status |
"failed" |
reason |
"Internal server failure" |
duration |
May be 0 if the failure occurred before the first segment was written |
回復
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);
});
注: アーカイブを再開する前に、そのセッションにまだアクティブな参加者がいることを必ず確認してください。 参加者がいないセッションでアーカイブを開始すると、エラーが発生します。
放送の中断
放送ノードに障害が発生すると、HLS または RTMP ストリームは終了し、放送は
"failed". ステータスコールバックが、指定されたブロードキャストステータスURLに送信されます。
コールバックのペイロード
{
"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"
}
回復
- 受け取る
"failed"ステータスコールバック。 - クライアントがセッションに再接続するまで待ちます(
connectionCreatedイベント、 または投票セッションの参加者)。 - 新しい放送を開始する:
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);
});
重要だ: HLSのURLは、新しい配信が行われるたびに変更されます。ストリームを再生するプレーヤーや 下流システムについては、必ず新しいURLに更新してください。
SIP通話の障害
SIPゲートウェイの障害によりアクティブなコールレッグが切断されると、SIP接続は終了し、
プラットフォームは callDestroyed セッション監視エンドポイントに、以下の方法で
reason_message: "Unexpected Clearing".
コールバックのペイロード
{
"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
}
}
回復
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);
});
キャプションの表示不具合
字幕エンジンに障害が発生すると、ライブ文字起こしは停止し、その字幕セッションは
"failed". ステータスコールバックが、キャプションのステータスURLに送信されます。
コールバックのペイロード
{
"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"
}
回復
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);
});
ベストプラクティス
- 必ず
reasonフィールド、ただし、それだけに頼ってはいけません。混乱は 通常、"Internal server failure", 回復ロジックでは、予期しないあらゆる事態を"failed"ステータス、または<something>Destroyedこのイベントを、プラットフォームの変革をもたらす可能性のある出来事として捉える。 - 冪等なリカバリハンドラを実装する。 コールバックは複数回配信される場合があります。
リソース ID (
archive.id,captionsId,session.id) 重複排除を行う。 - 回転前の警告を表示してください。 について
sessionNotificationイベント(~付き)remainingTime: 3600または14400) では、予定されているローテーションについて事前に通知されます。これを利用して、ローテーションの前にアーカイブ、 放送、字幕を適切に停止させ、ハード"forceDisconnected"解約。 - すべての障害事象を記録する 事後分析のために、全積載量で。その
timestampこのフィールドは、影響の継続時間を算出するための基準値となります。 - セッションについては、「セッション移行」を優先してください。 セッション移行を有効にすると、 クライアントを正常なサーバーへ透過的に移行することで、Media Routerの障害による影響範囲を劇的に縮小できます。 詳細はこちら サーバーのローテーションとセッションの移行.
- でアラートを設定する
"Internal server failure"コールバック。 の急増Internal server failure複数のセッションにまたがる事象は、より広範囲にわたるプラットフォームの障害の初期兆候である。