logo
当前页

呼叫邀请


功能简介

ZIM SDK 提供了呼叫邀请功能,支持主叫向被叫(可为离线状态)发送呼叫邀请、被叫(可为离线状态)接受或拒绝邀请等完整的业务流程控制能力。呼叫邀请分为两种模式,普通模式与进阶模式。

普通模式的呼叫邀请支持用户发起、取消、接受、拒绝和超时未响应。在此基础上,进阶模式的呼叫邀请还允许用户中途邀请他人、退出以及结束呼叫。

说明

“呼叫邀请” 功能仅提供了基本的业务流程控制能力,开发者需要自行实现使用本功能的业务需求(例如,通常应用在聊天工具中,发起语音通话或视频通话邀请等场景中)。

呼叫用户状态说明

呼叫用户状态( ZIMCallUserState ),是指用户在呼叫邀请各个环节中的状态。本节主要介绍状态如何流转,以及状态与接口/回调的关系。

状态流转

从呼叫邀请发起到呼叫结束,呼叫用户状态流转如下图所示:

状态含义触发事件适用模式
Inviting被邀请中。用户正在被邀请。
  • 普通模式。
  • 进阶模式。
Accepted已接受邀请。
  • 用户发起呼叫邀请。
  • 用户接受呼叫邀请。
Rejected已拒绝邀请。用户拒绝呼叫邀请。
Cancelled已取消邀请。
  • 用户主动取消呼叫邀请.
  • 被叫尚未应答邀请,而主叫掉线且心跳超时。
Received已收到邀请。
  • 在线用户收到邀请。
  • 离线用户在超时范围内上线。
Timeout超时未接受。被叫用户超时未响应邀请。
Quit退出。呼叫实现后,用户退出呼叫。
  • 进阶模式。
Unknown未知。请联系 ZEGO 技术支持。

状态与接口/回调的关系

在用户在进行呼叫邀请时,其呼叫用户状态会影响用户是否可以调用某些接口,或者监听某些事件。

  • 各状态可调用接口:
callInvitecallCancelcallAcceptcallRejectcallInvitecallQuitcallEnd
Inviting与呼叫用户状态无关,只需用户不在呼叫中,即可调用。与呼叫用户状态无关,只需用户发起邀请后,无人应答即可调用。✔️✔️
Accepted✔️✔️✔️
Rejected
Cancelled
Received✔️✔️
Timeout
Quit
Unknown
  • 各状态可监听事件:
onCallInvitationReceivedonCallInvitationTimeoutonCallInvitationCancelledonCallInvitationEndedonCallUserStateChanged
Inviting✔️✔️✔️✔️✔️
Accepted✔️✔️
Rejected
Cancelled
Received✔️✔️✔️
Timeout
Quit✔️
Unknown

普通模式

普通模式下,呼叫邀请的生命周期在全员响应后随即结束(所有被叫接受、拒绝、邀请超时之后)。以下,我们以客户端 A(邀请者)向客户端 B(被邀请者)发起呼叫邀请为例。

1 监听呼叫邀请相关用户的状态变化

开发者可以监听 callUserStateChanged 回调,进而收到呼叫邀请相关用户的状态变化。

示例代码

Untitled
// 监听呼叫邀请相关用户的状态变化
zim.on('callUserStateChanged', (zim, info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        const { userID, state, extendedData } = userInfo;
        // 您的业务逻辑
    });
})
1
Copied!

2 发起呼叫邀请

客户端 A 向客户端 B 发起呼叫邀请时,流程如下:

  1. 客户端 A 注册 callInvitationCreated 回调接口,以便接收呼叫邀请已创建的通知;客户端 B 通过注册 callInvitationReceived 回调接口,以便接收客户端 A 的邀请通知。

  2. 客户端 A 通过调用 callInvite 接口,发起呼叫邀请,客户端 B 在收到邀请信息后,可以选择 接受 或者 拒绝

    说明

    若客户端 B 为离线用户:

示例代码

  • 发送呼叫邀请
Untitled
/** 向在线用户发送呼叫邀请 */
var invitees = ['xxxx'];  // 被邀请人ID列表
var config = { timeout: 200 }; //邀请超时时间,单位为秒,范围1-600   
zim.callInvite(invitees, config)
    .then(({ callID, timeout, errorInvitees }) => {
        // 操作成功,此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    })
    .catch(err => {
        // 操作失败
    })
1
Copied!
Untitled
/** 向离线用户发送呼叫邀请 */
var invitees = ['xxxx'];  // 被邀请人 ID 列表
// 如需向离线用户推送呼叫邀请相关离线消息,需要配置 pushConfig,且已集成 ZPNs SDK
var pushConfig = {
    title: 'push title',
    content: 'push content',
    payload: 'push payload'
};

var config = { 
    timeout: 200, // 邀请超时时间,单位为秒,范围1-600
    extendedData: 'your call invite extendedData',
    pushConfig,
};
zim.callInvite(invitees, config)
    .then(({ callID, timeout, errorInvitees }) => {
        // 操作成功
        // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    })
    .catch(err => {
        // 操作失败
    })
1
Copied!
  • 邀请发起者收到呼叫邀请已创建的通知,示例代码如下:
Untitled
/** 邀请发起者收到呼叫邀请已创建的通知 */
zim.on('callInvitationCreated', (zim, info) => {
    // console.log('callInvitationCreated', info)
})
1
Copied!
  • 被邀请者收到邀请后的回调通知
Untitled
/** 被邀请者收到邀请后的回调通知 */
zim.on('callInvitationReceived', (zim, { callID, inviter, timeout, extendedData }) => {
    // console.log('callInvitationReceived', { callID, inviter, timeout, extendedData })
})
1
Copied!

3 取消呼叫邀请

客户端 A 向客户端 B 发起呼叫邀请后、又取消邀请时,流程如下:

  1. 客户端 A 发起呼叫邀请后,如果需要取消,可以调用 callCancel 接口,主动选择取消当前邀请。

    说明

    在呼叫邀请成功创建后至其超时前,如果没有任何被叫用户接受,主叫用户主动登出或因心跳超时而掉线,也会导致呼叫邀请被取消。

  2. 邀请取消后,客户端 B 会收到 callInvitationCancelled 回调接口的相关通知。

示例代码

  • 取消呼叫邀请
Untitled
// 取消呼叫邀请
var callID = 'xxxx';
var invitees = ['xxxx'];  // 被邀请人ID列表
var config = { extendedData: 'xxxx' }; 
zim.callCancel(invitees, callID, config)
    .then(res => {
        // 操作成功
    })
    .catch(err => {
        // 操作失败
    })
1
Copied!
  • 被邀请者收到取消邀请后的回调通知
Untitled
// 被邀请者收到取消邀请后的回调通知
zim.on('callInvitationCancelled',(zim, { callID, inviter, extendedData }) => {
    // console.log('callInvitationCancelled', { callID, inviter, extendedData })
})
1
Copied!

4 接受呼叫邀请

客户端 B 收到客户端 A 的呼叫邀请后,选择接受邀请时,流程如下:

  1. 客户端 B 收到客户端 A 发来的呼叫邀请后,通过调用 callAccept 接口,接受该邀请。
  2. 客户端 B 接受邀请后,客户端 A 可以通过 callUserStateChanged 回调接口,收到相关通知。如果是在多人呼叫中,则所有现有呼叫成员都可通过此回调收到相关通知。

示例代码

  • 接受呼叫邀请
Untitled
// 接受呼叫邀请
var callID = 'xxxx';
var config = { extendedData: 'xxxx' }; 
zim.callAccept(callID, config)
    .then(res => {
        // 操作成功
    })
    .catch(err => {
        // 操作失败
    })
1
Copied!
  • 呼叫成员收到有用户接受呼叫邀请的通知
Untitled
// 邀请者接受邀请后的回调通知
zim.on('callUserStateChanged', (zim, info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        const { userID, state, extendedData } = userInfo;
        // state = 1 表示接受,具体可以参考枚举 ZIMCallUserState
        if (state == 1) {
            // 您的业务逻辑
        } 
    });
})
1
Copied!

5 拒绝呼叫邀请

客户端 B 收到客户端 A 的呼叫邀请后,选择拒绝邀请时,流程如下:

  1. 客户端 B 收到客户端 A 发来的呼叫邀请后,通过调用 callReject 接口,拒绝该邀请。
  2. 客户端 B 拒绝邀请后,客户端 A 可以通过 callUserStateChanged 回调接口,收到相关通知。如果是在多人呼叫中,则所有现有呼叫成员都可通过此回调收到相关通知。

示例代码

  • 拒绝呼叫邀请
Untitled
// 拒绝呼叫邀请
var callID = 'xxxx';
var config = { extendedData: 'xxxx' }; 
zim.callReject(callID, config)
    .then(res => {
        // 操作成功
    })
    .catch(err => {
        // 操作失败
    })
1
Copied!
  • 呼叫成员收到有用户拒绝呼叫邀请的通知
Untitled
// 邀请者拒绝邀请后的回调通知
zim.on('callUserStateChanged', (zim, info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        const { userID, state, extendedData } = userInfo;
        // state = 2 表示拒绝,具体可以参考枚举 ZIMCallUserState
        if (state == 2) {
            // 您的业务逻辑
        }        
    });
})
1
Copied!

6 超时未响应呼叫邀请

客户端 B 收到客户端 A 的呼叫邀请后,客户端 B 长时间未响应时,流程如下:

  1. 客户端 A(邀请者)通过 callUserStateChanged 回调接口,收到邀请超时、客户端未响应的通知。如果是在多人呼叫中,则所有现有呼叫成员都可通过此回调收到相关通知。
  2. 客户端 B(被邀请者)通过 callInvitationTimeout 回调接口,收到邀请超时、自己未响应的通知。
  • 邀请者收到的回调:
Untitled
zim.on('callUserStateChanged', (zim, info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        const { userID, state, extendedData } = userInfo;
        // state = 6 表示超时,具体可以参考枚举 ZIMCallUserState
        if (state == 6) {
            // 您的业务逻辑
        }
    });
})
1
Copied!
  • 被邀请者收到的回调:
Untitled
// 被邀请者响应超时后,“被邀请者”收到的回调通知,超时时间单位:秒
zim.on('callInvitationTimeout', (zim, { callID }) => {
    // console.log('callInvitationTimeout', { callID })
})
1
Copied!

进阶模式

如果您想要实现更为丰富的用户状态场景,比如多人呼叫邀请业务场景,可以参考本节内容实现进阶模式的呼叫邀请。

发起进阶模式的呼叫邀请后,呼叫邀请的生命周期延长至用户主动调用 callEnd 接口结束呼叫。在结束呼叫之前,用户还可以实现在呼叫中继续邀请他人以及退出呼叫的功能。

发起进阶模式的呼叫邀请

开发者在调用 callInvite 接口时主动设置模式为进阶模式,才能发起进阶模式的呼叫邀请。

示例代码

Untitled
/** 向在线用户发送呼叫邀请 - 进阶模式 */
var invitees = ['xxxx'];  // 被邀请人ID列表
 // 邀请超时时间,单位为秒,范围 1 - 600
//  mode 为呼叫邀请模式,1 表示进阶模式。
var config = { timeout: 200, mode: 1 };
zim.callInvite(invitees, config)
    .then(({ callID, timeout, errorInvitees }) => {
        // 操作成功
        // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    })
    .catch(err => {
        // 操作失败
    })
1
Copied!
说明

除了发起外,呼叫邀请的进阶模式和普通模式在取消、接受、拒绝和超时未响应上没有差别。

呼叫中邀请

在创建进阶模式呼叫邀请后,状态为 Accepted 的用户可以调用 callingInvite 接口向不在本呼叫中的用户发起邀请。但是,同一个呼叫中的参与用户不能超过 10 人(含邀请创建用户)。

示例代码

  • 呼叫中邀请
Untitled
// 呼叫中邀请
const config = { timeout: 60, extendedData: 'callingInvite extendedData' };
const userList = [];
// callID 通过创建进阶模式呼叫邀请的回调获取。
zim.callingInvite(userList, 'callID', config)
    .then(res => {
        // 操作成功
    }).catch(err => {
        // 操作失败
    });
1
Copied!

主动加入呼叫或切换设备

实现进阶模式呼叫邀请后,以下两种情况下,可以调用 callJoin 接口:

  • 没有加入呼叫的用户希望加入呼叫。
    • 对于呼叫外用户加入成功的场景,该用户的状态将流转为 accepted,此时呼叫中的所有用户收到 callUserStateChanged 的通知回调。
  • 多端登录用户使用设备 A 发起或接受邀请后,希望让其他设备成为新的主设备
    • 对于切换设备的场景,呼叫内其他用户无感知。
说明
  • 主设备,是指主动调用发起、接受或加入呼叫接口参与呼叫的设备。
  • 只有主设备能感知呼叫邀请的变化,其他设备只能通过查询呼叫邀请列表来获取呼叫邀请内的数据。

示例代码

Untitled
// 主动加入呼叫或切换设备

const config = { extendedData: 'callJoin extendedData' };
zim.callJoin('callID', config)
    .then(res => {
        // 操作成功
    }).catch(err => {
        // 操作失败
    });
1
Copied!

退出呼叫

实现进阶模式呼叫邀请后,呼叫用户状态为 Accepted 的用户可调用 callQuit 接口退出呼叫。退出成功后,该用户的状态将流转为 quit,该用户和仍在呼叫中的其他用户都将会收到 callUserStateChanged 的通知回调。

示例代码

  • 退出呼叫
Untitled
// 退出呼叫
const config = { extendedData: 'callQuit extendedData' };
zim.callQuit('callID', config).then(res => {
        // 操作成功
    }).catch(err => {
        // 操作失败
    });
1
Copied!
  • 呼叫成员收到有用户退出呼叫的通知
Untitled
// 退出用户本人和用户状态为 “inviting”, “received” 和 “accept” 的其他用户可在此处收到有用户员退出邀请的通知       
zim.on('callUserStateChanged', (zim, info) => {
    // callID 通过创建进阶模式呼叫邀请的回调获取
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        const { userID, state, extendedData } = userInfo;
        // state = 7 表示退出,具体可以参考枚举 ZIMCallUserState
        if (state == 7) {
            // 您的业务逻辑
        }
        
    });
})
1
Copied!

结束呼叫

实现进阶模式呼叫邀请后,呼叫用户状态为 Accepted 的用户可调用 callEnd 接口结束呼叫。此后,所有人的状态保持不变,该呼叫的状态(callState)变为 end,状态为 InivitingAcceptedReceived 的用户将会收到 callInvitationEnded 的通知回调。

示例代码

  • 结束呼叫
Untitled
// 结束呼叫
const config = { extendedData: 'callEnd extendedData' };
// callID 通过创建进阶模式呼叫邀请的回调获取
zim.callEnd('callID', config).then(res => {
    // 操作成功
}).catch(err => {
    // 操作失败
});
1
Copied!
  • 呼叫成员收到呼叫结束的通知
Untitled
// 呼叫成员收到的回调通知
zim.on('callInvitationEnded', (zim, info) => {
    // console.log('callInvitationEnded', info)
})
1
Copied!

呼叫邀请离线推送

  • 可选)如需实现呼叫邀请离线推送,请参考下表。
呼叫邀请离线推送发起端呼叫邀请离线推送接收端接收端配置参考文档
  • iOS
  • Android
  • macOS
  • Windows
  • Web
  • 小程序
  • iOS
  • Android

更多功能

检测邀请是否送达

如需让邀请内在线用户了解其他用户是否收到邀请,从而实现相关业务逻辑,请在发起呼叫邀请时,将 ZIMCallInviteConfig 中的 enableNotReceivedCheck 修改为 true,从而开始检测邀请是否送达。

Untitled
/** 向用户发送呼叫邀请 */
var invitees = ['xxxx'];  // 被邀请人ID列表
var config = { 
    timeout: 200, // 邀请超时时间,单位为秒,范围1-600  
    enableNotReceivedCheck: true // 开启暂未送达检测
};  
zim.callInvite(invitees, config)
    .then(({ callID, timeout, errorInvitees }) => {
        // 操作成功,此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    })
    .catch(err => {
        // 操作失败
    })
1
Copied!

主叫发起呼叫邀请后,如果被叫在 5 秒内(可联系 ZEGO 技术支持将间隔调整为 3 秒或 4 秒)因断网未上线等原因没有接收到本次邀请:

  • 若该被叫客户端使用 2.14.0 之后版本的 ZIM SDK,其用户状态将会流转为 ZIMCallUserState.NOT_YET_RECEIVED,表示邀请暂未送达。此时可实现业务逻辑,向呼叫邀请内在线用户展示“该用户可能不在线,暂时无法接收呼叫邀请”等 UI 提示。
  • 若该被叫客户端使用 2.14.0 及之前版本的 ZIM SDK,其用户状态仍然保持为 ZIMCallUserState.INVITING。如果该状态保持 5 秒以上,也可以实现上述业务逻辑。

随后,如果在邀请超时前,该被叫用户上线并接收该邀请,该成员的用户状态将流转为 ZIMCallUserState.RECEIVED

查询呼叫邀请列表

通过调用 queryCallInvitationList 接口,用户可以查询与自己相关的呼叫邀请列表,单次查询上限为 100 条,超过 100 条按 100 处理。

Untitled
/** 
  * 查询呼叫邀请列表
  * 1. 查询用户自己的呼叫邀请列表, 单次查询 20 条呼叫邀请数据  
  * 2. 首次查询 nextFlag 填 0,代表从最新的呼叫邀请(创建时间最晚)开始
  */
const config = { count: 20, nextFlag: 0 };
zim.queryCallInvitationList(config).then(res => {
    const { callList, nextFlag } = res;
    // next page
    config.nextFlag = nextFlag;
    zim.queryCallInvitationList(config);
});
1
Copied!

Previous

实现流程

Next

实现离线推送