保留中の通話招待を復元する

ユーザーが着信招待を受け取り、応答する前にページを更新(またはアプリを再起動)した場合、Client SDKは追加のAPI呼び出しを必要とせずに、招待を自動的に再送信することができます。

これが機能するのは、Conversation Service が保留中のイベントを約 30秒. 前のセッションIDを createSession, サーバーはそれらのイベントを新しいセッションで再生し、その callInvite イベント(または onCallInvite (デリゲート)が自動的に実行されます。

仕組み

  1. セッションIDを保持する で返される。 createSession (例:~において sessionStorage ウェブ上で、または UserDefaults / SharedPreferences (モバイル版)。
  2. 次の読み込み時に, 保存されたセッションIDを取得し、それを createSession.
  3. 呼び出す前に、inviteリスナーを登録してください createSession そのため、保留中のイベントがディスパッチされる時点では、すでに設定済みとなっています。

警告だ: 「The Conversation」サービスでは、保留中のイベントは約30秒間保持されます。最初の招待が届いてからそれ以上の時間が経過している場合、再配信は行われません。

エッジケース

  • ウィンドウの有効期限が切れました: 30秒の保持期間が経過した場合、 createSession それでも処理は成功します。有効なセッションは取得できますが、保留中の招待は再送信されません。その時点で、発信者はタイムアウトしているか、キャンセルしているでしょう。
  • 無効なセッションID: 保存されているセッション ID が無効であるか、別のユーザーのものである場合、SDK はその ID を無視して新しいセッションを作成します。保留中のイベントは再生されません。
  • アプリの強制終了 vs ページのリフレッシュ: ウェブ上では、 sessionStorage タブが閉じられるとクリアされるため、このパターンはタブ内での更新には有効です。モバイルアプリの再起動時には、セッションIDを永続ストレージに保存してください(UserDefaults / SharedPreferences).

例

client.on('callInvite', (callId, from) => {
  console.log(`Received call invite ${callId} from ${from}`);
});

const previousSessionId = store.getSessionId();

try {
  const sessionId = previousSessionId
    ? await client.createSession(jwt, previousSessionId)
    : await client.createSession(jwt);

  store.saveSessionId(sessionId);
  console.log(`Session ready: ${sessionId}`);
} catch (error) {
  console.error('Failed to create/reconnect session', error);
}
 client.setCallInviteListener { callId, from, channelType ->
     println("Received call invite $callId from $from on $channelType")
 }

 val previousSessionId = store.getSessionId()
 if (previousSessionId != null) {
     client.createSession(jwt, previousSessionId) { error, sessionId ->
         if (error != null) {
             println("Failed to reconnect session: $error")
             return@createSession
         }

         sessionId?.let(store::saveSessionId)
         println("Reconnected session: $sessionId")
     }
 } else {
     client.createSession(jwt) { error, sessionId ->
         if (error != null) {
             println("Failed to create session: $error")
             return@createSession
         }

         sessionId?.let(store::saveSessionId)
         println("Session created: $sessionId")
     }
 }
 client.setCallInviteListener((callId, from, channelType) -> {
     System.out.println(
             "Received call invite " + callId + " from " + from + " on " + channelType
     );
     return null;
 });

 String previousSessionId = store.getSessionId();
 if (previousSessionId != null) {
     client.createSession(jwt, previousSessionId, (error, sessionId) -> {
         if (error != null) {
             System.out.println("Failed to reconnect session: " + error);
             return null;
         }

         if (sessionId != null) {
             store.saveSessionId(sessionId);
         }
         System.out.println("Reconnected session: " + sessionId);
         return null;
     });
 } else {
     client.createSession(jwt, null, (error, sessionId) -> {
         if (error != null) {
             System.out.println("Failed to create session: " + error);
             return null;
         }

         if (sessionId != null) {
             store.saveSessionId(sessionId);
         }
         System.out.println("Session created: " + sessionId);
         return null;
     });
 }
 class InviteDelegate: NSObject, VGVoiceClientDelegate {
     func voiceClient(_ client: VGVoiceClient, didReceiveInviteForCall callId: VGCallId, from caller: String, with type: VGVoiceChannelType) {
         print("Received call invite \(callId) from \(caller)")
     }

     func voiceClient(_ client: VGVoiceClient, didReceiveHangupForCall callId: VGCallId, withQuality callQuality: VGRTCQuality, reason: VGHangupReason) {}
     func voiceClient(_ client: VGVoiceClient, didReceiveInviteCancelForCall callId: VGCallId, with reason: VGVoiceInviteCancelReason) {}
     func client(_ client: VGBaseClient, didReceiveSessionErrorWith reason: VGSessionErrorReason) {}
 }

 let delegate = InviteDelegate()
 client.delegate = delegate

 if let previousSessionId = store.getSessionId() {
     client.createSession(jwt, sessionId: previousSessionId) { error, sessionId in
         guard error == nil, let sessionId = sessionId else {
             print("Failed to reconnect session: \(error?.localizedDescription ?? "unknown")")
             return
         }

         store.saveSessionId(sessionId)
         print("Reconnected session: \(sessionId)")
     }
 } else {
     client.createSession(jwt) { error, sessionId in
         guard error == nil, let sessionId = sessionId else {
             print("Failed to create session: \(error?.localizedDescription ?? "unknown")")
             return
         }

         store.saveSessionId(sessionId)
         print("Session created: \(sessionId)")
     }
 }
 self.store = store;
 client.delegate = self;

 NSString *previousSessionId = [store getSessionId];
 if (previousSessionId != nil) {
     [client createSession:jwt sessionId:previousSessionId callback:^(NSError * _Nullable error, NSString * _Nullable sessionId) {
         if (error != nil || sessionId == nil) {
             NSLog(@"Failed to reconnect session: %@", error);
             return;
         }

         [store saveSessionId:sessionId];
         NSLog(@"Reconnected session: %@", sessionId);
     }];
 } else {
     [client createSession:jwt callback:^(NSError * _Nullable error, NSString * _Nullable sessionId) {
         if (error != nil || sessionId == nil) {
             NSLog(@"Failed to create session: %@", error);
             return;
         }

         [store saveSessionId:sessionId];
         NSLog(@"Session created: %@", sessionId);
     }];
 }