呼叫邀请
功能简介
ZIM SDK 提供了呼叫邀请功能,支持主叫向被叫(可为离线状态)发送呼叫邀请、被叫(可为离线状态)接受或拒绝邀请等完整的业务流程控制能力。呼叫邀请分为两种模式,普通模式与进阶模式。
普通模式的呼叫邀请支持用户发起、取消、接受、拒绝和超时未响应。在此基础上,进阶模式的呼叫邀请还允许用户中途邀请他人、退出以及结束呼叫。
“呼叫邀请” 功能仅提供了基本的业务流程控制能力,开发者需要自行实现使用本功能的业务需求(例如,通常应用在聊天工具中,发起语音通话或视频通话邀请等场景中)。
呼叫用户状态说明
呼叫用户状态( ZIMCallUserState ),是指用户在呼叫邀请各个环节中的状态。本节主要介绍状态如何流转,以及状态与接口/回调的关系。
状态流转
从呼叫邀请发起到呼叫结束,呼叫用户状态流转如下图所示:

| 状态 | 含义 | 触发事件 | 适用模式 | 
|---|---|---|---|
| Inviting | 被邀请中。 | 用户正在被邀请。 | 
 | 
| Accepted | 已接受邀请。 | 
 | |
| Rejected | 已拒绝邀请。 | 用户拒绝呼叫邀请。 | |
| Cancelled | 已取消邀请。 | 
 | |
| Received | 已收到邀请。 | 
 | |
| Timeout | 超时未接受。 | 被叫用户超时未响应邀请。 | |
| Quit | 退出。 | 呼叫实现后,用户退出呼叫。 | 
 | 
| Unknown | 未知。 | 请联系 ZEGO 技术支持。 | |
状态与接口/回调的关系
在用户在进行呼叫邀请时,其呼叫用户状态会影响用户是否可以调用某些接口,或者监听某些事件。
- 各状态可调用接口:
| callInvite | callCancel | callAccept | callReject | callInvite | callQuit | callEnd | |
|---|---|---|---|---|---|---|---|
| Inviting | 与呼叫用户状态无关,只需用户不在呼叫中,即可调用。 | 与呼叫用户状态无关,只需用户发起邀请后,无人应答即可调用。 | ✔️ | ✔️ | ✖ | ✖ | ✖ | 
| Accepted | ✖ | ✖ | ✔️ | ✔️ | ✔️ | ||
| Rejected | ✖ | ✖ | ✖ | ✖ | ✖ | ||
| Cancelled | ✖ | ✖ | ✖ | ✖ | ✖ | ||
| Received | ✔️ | ✔️ | ✖ | ✖ | ✖ | ||
| Timeout | ✖ | ✖ | ✖ | ✖ | ✖ | ||
| Quit | ✖ | ✖ | ✖ | ✖ | ✖ | ||
| Unknown | ✖ | ✖ | ✖ | ✖ | ✖ | 
- 各状态可监听事件:
| onCallInvitationReceived | onCallInvitationTimeout | onCallInvitationCancelled | onCallInvitationEnded | onCallUserStateChanged | |
|---|---|---|---|---|---|
| Inviting | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | 
| Accepted | ✖ | ✖ | ✖ | ✔️ | ✔️ | 
| Rejected | ✖ | ✖ | ✖ | ✖ | ✖ | 
| Cancelled | ✖ | ✖ | ✖ | ✖ | ✖ | 
| Received | ✖ | ✖ | ✔️ | ✔️ | ✔️ | 
| Timeout | ✖ | ✖ | ✖ | ✖ | ✖ | 
| Quit | ✖ | ✖ | ✖ | ✖ | ✔️ | 
| Unknown | ✖ | ✖ | ✖ | ✖ | ✖ | 
普通模式
普通模式下,呼叫邀请的生命周期在全员响应后随即结束(所有被叫接受、拒绝、邀请超时之后)。以下,我们以客户端 A(邀请者)向客户端 B(被邀请者)发起呼叫邀请为例。
1 监听邀请者和被邀请者的状态变化
开发者可以监听 onCallUserStateChanged 回调,进而收到呼叫邀请相关用户的状态变化。
// 监听邀请者和被邀请者的状态变化
@Override
public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID) {
    super.onCallUserStateChanged(zim, info, callID);
    for(ZIMCallUserInfo userInfo : info.callUserList){
        // 状态发生变化的 userID
        String userID = userInfo.userID;
        // 该用户当前最新状态
        ZIMCallUserState state = userInfo.state;
        // 透传字段,与用户调用接受、拒绝、退出接口时携带的 extended data 内容一致
        String extendedData = userInfo.extendedData;
    }
}// 监听邀请者和被邀请者的状态变化
@Override
public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID) {
    super.onCallUserStateChanged(zim, info, callID);
    for(ZIMCallUserInfo userInfo : info.callUserList){
        // 状态发生变化的 userID
        String userID = userInfo.userID;
        // 该用户当前最新状态
        ZIMCallUserState state = userInfo.state;
        // 透传字段,与用户调用接受、拒绝、退出接口时携带的 extended data 内容一致
        String extendedData = userInfo.extendedData;
    }
}// 监听邀请者和被邀请者的状态变化
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    for(ZIMCallUserInfo userInfo in callUserStateChangeInfo.callUserList){
        // 状态发生变化的 userID
        String userID = userInfo.userID;
        // 该用户当前最新的状态
        ZIMCallUserState state = userInfo.state;
        // 透传字段,与用户调用接受、拒绝、退出接口时携带的 extended data 内容一致
        String extendedData = userInfo.extendedData;
    }
};// 监听邀请者和被邀请者的状态变化
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    for(ZIMCallUserInfo userInfo in callUserStateChangeInfo.callUserList){
        // 状态发生变化的 userID
        String userID = userInfo.userID;
        // 该用户当前最新的状态
        ZIMCallUserState state = userInfo.state;
        // 透传字段,与用户调用接受、拒绝、退出接口时携带的 extended data 内容一致
        String extendedData = userInfo.extendedData;
    }
};// 监听邀请者和被邀请者的状态变化
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    for (ZIMCallUserInfo *userInfo in info.callUserList) {
        // 用户状态发生变化的 userID
        NSString *userID = userInfo.userID;
        
        // 该用户当前最新的用户状态
        ZIMCallUserState state = userInfo.state;
        
        // 透传字段,与用户调用接受、拒绝、退出接口时携带的 extended data 内容一致
        NSString *extendedData = userInfo.extendedData;
    }
}// 监听邀请者和被邀请者的状态变化
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    for (ZIMCallUserInfo *userInfo in info.callUserList) {
        // 用户状态发生变化的 userID
        NSString *userID = userInfo.userID;
        
        // 该用户当前最新的用户状态
        ZIMCallUserState state = userInfo.state;
        
        // 透传字段,与用户调用接受、拒绝、退出接口时携带的 extended data 内容一致
        NSString *extendedData = userInfo.extendedData;
    }
}// 监听邀请者和被邀请者的状态变化
void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info, const std::string & callID){
    for (const ZIMCallUserInfo &userInfo: info.callUserList) {
        // 状态发生变化的 userID
        std::string userID = userInfo.userID;
        // 当前最新状态
        ZIMCallUserState state = userInfo.state;
        // 透传字段,与用户调用接受、拒绝、退出接口时携带的 extended data 内容一致
        std::string extendedData = userInfo.extendedData;
    }
}// 监听邀请者和被邀请者的状态变化
void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info, const std::string & callID){
    for (const ZIMCallUserInfo &userInfo: info.callUserList) {
        // 状态发生变化的 userID
        std::string userID = userInfo.userID;
        // 当前最新状态
        ZIMCallUserState state = userInfo.state;
        // 透传字段,与用户调用接受、拒绝、退出接口时携带的 extended data 内容一致
        std::string extendedData = userInfo.extendedData;
    }
}// 监听邀请者和被邀请者的状态变化
zim.on('callUserStateChanged', (zim: ZIM, info: ZIMEventOfCallUserStateChangedResult) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
    });
})// 监听邀请者和被邀请者的状态变化
zim.on('callUserStateChanged', (zim: ZIM, info: ZIMEventOfCallUserStateChangedResult) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
    });
})// 监听邀请者和被邀请者的状态变化
zim.onCallUserStateChanged((info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
    });
})// 监听邀请者和被邀请者的状态变化
zim.onCallUserStateChanged((info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
    });
})2 发起呼叫邀请
客户端 A 向客户端 B 发起呼叫邀请时,流程如下:

- 
客户端 A 注册 onCallInvitationCreated 回调接口,以便接收呼叫邀请已创建的通知;客户端 B 通过注册 onCallInvitationReceived 回调接口,以便接收客户端 A 的邀请通知。 
- 
客户端 A 通过调用 callInvite 接口,发起呼叫邀请,客户端 B 在收到邀请信息后,可以选择 接受 或者 拒绝。 说明若客户端 B 为离线用户: - 在 timeout(邀请超时时间)内登录,即可通过 onCallInvitationReceived 收到呼叫邀请通知。
- 在 timeout 外登录,请调用 queryCallInvitationList 来 查询呼叫邀请列表。
 
- 发送呼叫邀请
// 发送呼叫邀请
List<String> invitees = new ArrayList<String>(); // 被邀请人列表
invitees.add("421234");       // 被邀请人id
ZIMCallInviteConfig config = new ZIMCallInviteConfig(); 
config.timeout = 200; // 邀请超时时间,单位为秒,范围 1-600 
// (可选)需要向离线用户发起呼叫邀请并推送相关离线通知时填写
ZIMPushConfig pushConfig = new ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;
zim.callInvite(invitees, config, new ZIMCallInvitationSentCallback() {
    @Override
    public void onCallInvitationSent(String callID, ZIMCallInvitationSentInfo info, ZIMError errorInfo) {
        // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    }
});// 发送呼叫邀请
List<String> invitees = new ArrayList<String>(); // 被邀请人列表
invitees.add("421234");       // 被邀请人id
ZIMCallInviteConfig config = new ZIMCallInviteConfig(); 
config.timeout = 200; // 邀请超时时间,单位为秒,范围 1-600 
// (可选)需要向离线用户发起呼叫邀请并推送相关离线通知时填写
ZIMPushConfig pushConfig = new ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;
zim.callInvite(invitees, config, new ZIMCallInvitationSentCallback() {
    @Override
    public void onCallInvitationSent(String callID, ZIMCallInvitationSentInfo info, ZIMError errorInfo) {
        // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    }
});// 发送呼叫邀请
List<String> invitees = []; // 被邀请人列表
invitees.add('1234'); //被邀请人 id
ZIMCallInviteConfig callInviteConfig = ZIMCallInviteConfig();
callInviteConfig.timeout = 200; //邀请超时时间,单位为秒,范围1-600
// (可选)需要向离线用户发起呼叫邀请时填写
ZIMPushConfig pushConfig = ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;
ZIM
    .getInstance()
    !.callInvite(invitees, callInviteConfig)
    .then((value) => {})
    .catchError((onError) {});// 发送呼叫邀请
List<String> invitees = []; // 被邀请人列表
invitees.add('1234'); //被邀请人 id
ZIMCallInviteConfig callInviteConfig = ZIMCallInviteConfig();
callInviteConfig.timeout = 200; //邀请超时时间,单位为秒,范围1-600
// (可选)需要向离线用户发起呼叫邀请时填写
ZIMPushConfig pushConfig = ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;
ZIM
    .getInstance()
    !.callInvite(invitees, callInviteConfig)
    .then((value) => {})
    .catchError((onError) {});// 发送呼叫邀请
NSArray<NSString *> * invitees = @[@"421234"];  // 被邀请人列表
ZIMCallInviteConfig *callInviteConfig = [[ZIMCallInviteConfig alloc] init]; 
// 设置邀请的超时时间
callInviteConfig.timeout = 200;
// (可选)需要向离线用户发起呼叫邀请并推送相关离线通知时填写
ZIMPushConfig *pushConfig = [[ZIMPushConfig alloc] init];
pushConfig.title = @"your title";
pushConfig.content = @"your content";
pushConfig.payload = @"your payload";
callInviteConfig.pushConfig = pushConfig;
[zim callInviteWithInvitees:invitees config:callInviteConfig callback:^(NSString *callID, ZIMCallInvitationSentInfo *info,ZIMError *errorInfo){
    // 这里填发送呼叫邀请后的回调
    // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
}];// 发送呼叫邀请
NSArray<NSString *> * invitees = @[@"421234"];  // 被邀请人列表
ZIMCallInviteConfig *callInviteConfig = [[ZIMCallInviteConfig alloc] init]; 
// 设置邀请的超时时间
callInviteConfig.timeout = 200;
// (可选)需要向离线用户发起呼叫邀请并推送相关离线通知时填写
ZIMPushConfig *pushConfig = [[ZIMPushConfig alloc] init];
pushConfig.title = @"your title";
pushConfig.content = @"your content";
pushConfig.payload = @"your payload";
callInviteConfig.pushConfig = pushConfig;
[zim callInviteWithInvitees:invitees config:callInviteConfig callback:^(NSString *callID, ZIMCallInvitationSentInfo *info,ZIMError *errorInfo){
    // 这里填发送呼叫邀请后的回调
    // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
}];// 定义回调
auto callinvite_callback = [=](std::string callID, zim::ZIMCallInvitationSentInfo info, zim::ZIMError errorInfo) {
    if (errorInfo.code != 0) {
        ShowMsg(L"发送呼叫邀请失败,callID: %s, 错误码: %d", callID, error_info.code);
    }    
    else {
        ShowMsg(L"发送呼叫邀请成功, callID: %s", callID);
    }
}
// 发起呼叫邀请
std::vector<std::string> invitees;  // 被邀请人列表
invitees.push_back("421234");       // 被邀请人id
zim::ZIMCallInviteConfig config;    
zim::ZIMPushConfig pushConfig;
// 离线推送标题,需要向离线用户发起呼叫邀请时,请填入该字段
pushConfig.title = "win_push_title";
// 离线推送内容,需要向离线用户发起呼叫邀请,请填入该字段
pushConfig.content = "win_push_content";
// 离线推送附加字段,需要向离线用户发起呼叫邀请时带上额外信息,可酌情填入该字段
pushConfig.payload = "win_push_payload";
config.pushConfig = &pushConfig;
zim_->callInvite(invitees, config, callinvite_callback); //发送呼叫邀请// 定义回调
auto callinvite_callback = [=](std::string callID, zim::ZIMCallInvitationSentInfo info, zim::ZIMError errorInfo) {
    if (errorInfo.code != 0) {
        ShowMsg(L"发送呼叫邀请失败,callID: %s, 错误码: %d", callID, error_info.code);
    }    
    else {
        ShowMsg(L"发送呼叫邀请成功, callID: %s", callID);
    }
}
// 发起呼叫邀请
std::vector<std::string> invitees;  // 被邀请人列表
invitees.push_back("421234");       // 被邀请人id
zim::ZIMCallInviteConfig config;    
zim::ZIMPushConfig pushConfig;
// 离线推送标题,需要向离线用户发起呼叫邀请时,请填入该字段
pushConfig.title = "win_push_title";
// 离线推送内容,需要向离线用户发起呼叫邀请,请填入该字段
pushConfig.content = "win_push_content";
// 离线推送附加字段,需要向离线用户发起呼叫邀请时带上额外信息,可酌情填入该字段
pushConfig.payload = "win_push_payload";
config.pushConfig = &pushConfig;
zim_->callInvite(invitees, config, callinvite_callback); //发送呼叫邀请向在线用户发送呼叫邀请
/** 向在线用户发送呼叫邀请 */
const invitees = ['xxxx'];  // 被邀请人ID列表
const config: ZIMCallInviteConfig = {
    mode: 0,
    extendedData: '', 
    timeout: 200 //邀请超时时间,单位为秒,范围1-600   
};
zim.callInvite(invitees, config)
    .then((res: ZIMCallInvitationSentResult) => {
        const callID = res.callID;
        // 操作成功,此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })/** 向在线用户发送呼叫邀请 */
const invitees = ['xxxx'];  // 被邀请人ID列表
const config: ZIMCallInviteConfig = {
    mode: 0,
    extendedData: '', 
    timeout: 200 //邀请超时时间,单位为秒,范围1-600   
};
zim.callInvite(invitees, config)
    .then((res: ZIMCallInvitationSentResult) => {
        const callID = res.callID;
        // 操作成功,此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })- 邀请发起者收到呼叫邀请已创建的通知,示例代码如下:
/** 邀请发起者收到呼叫邀请已创建的通知 */
zim.setEventHandler(new ZIMEventHandler() {
      @Override
    public void onCallInvitationCreated(ZIM zim, ZIMCallInvitationCreatedInfo info, String callID) {
    
    }
});/** 邀请发起者收到呼叫邀请已创建的通知 */
zim.setEventHandler(new ZIMEventHandler() {
      @Override
    public void onCallInvitationCreated(ZIM zim, ZIMCallInvitationCreatedInfo info, String callID) {
    
    }
});/** 邀请发起者收到呼叫邀请已创建的通知 */
ZIMEventHandler.onCallInvitationCreated = (ZIM zim, ZIMCallInvitationCreatedInfo info, String callID){
};/** 邀请发起者收到呼叫邀请已创建的通知 */
ZIMEventHandler.onCallInvitationCreated = (ZIM zim, ZIMCallInvitationCreatedInfo info, String callID){
};/** 邀请发起者收到呼叫邀请已创建的通知 */
- (void)zim:(ZIM *)zim
    callInvitationCreated:(ZIMCallInvitationCreatedInfo *)info
                callID:(NSString *)callID{
    // 这里填呼叫邀请发起者收到邀请创建成功的回调通知
}/** 邀请发起者收到呼叫邀请已创建的通知 */
- (void)zim:(ZIM *)zim
    callInvitationCreated:(ZIMCallInvitationCreatedInfo *)info
                callID:(NSString *)callID{
    // 这里填呼叫邀请发起者收到邀请创建成功的回调通知
}/** 邀请发起者收到呼叫邀请已创建的通知 */
virtual void onCallInvitationCreated(ZIM * /*zim*/,
                                      const ZIMCallInvitationCreatedInfo & /*info*/,
                                      const std::string & /*callID*/) {
    // 这里可以进行相关的 UI 操作
}/** 邀请发起者收到呼叫邀请已创建的通知 */
virtual void onCallInvitationCreated(ZIM * /*zim*/,
                                      const ZIMCallInvitationCreatedInfo & /*info*/,
                                      const std::string & /*callID*/) {
    // 这里可以进行相关的 UI 操作
}/** 邀请发起者收到呼叫邀请已创建的通知 */
zim.on('callInvitationCreated', (zim: ZIM, info: ZIMEventOfCallInvitationCreatedResult) => {
    // console.log('callInvitationCreated', info)
})/** 邀请发起者收到呼叫邀请已创建的通知 */
zim.on('callInvitationCreated', (zim: ZIM, info: ZIMEventOfCallInvitationCreatedResult) => {
    // console.log('callInvitationCreated', info)
})/** 邀请发起者收到呼叫邀请已创建的通知 */
zim.onCallInvitationCreated((info) => {
    // console.log('onCallInvitationCreated', info)
})/** 邀请发起者收到呼叫邀请已创建的通知 */
zim.onCallInvitationCreated((info) => {
    // console.log('onCallInvitationCreated', info)
})- 被邀请者收到邀请后的回调通知
// 被邀请者收到邀请后的回调通知
zim.setEventHandler(new ZIMEventHandler() {
    @Override
    void onCallInvitationReceived(ZIM zim, ZIMCallInvitationReceivedInfo info, String callID) {
    } 
});// 被邀请者收到邀请后的回调通知
zim.setEventHandler(new ZIMEventHandler() {
    @Override
    void onCallInvitationReceived(ZIM zim, ZIMCallInvitationReceivedInfo info, String callID) {
    } 
});//被邀请者收到邀请后的回调通知
ZIMEventHandler.onCallInvitationReceived = (zim, info, callID) {
    
};//被邀请者收到邀请后的回调通知
ZIMEventHandler.onCallInvitationReceived = (zim, info, callID) {
    
};// 被邀请者收到邀请后的回调通知
- (void)zim:(ZIM *)zim
    callInvitationReceived:(ZIMCallInvitationReceivedInfo *)info
                    callID:(NSString *)callID{
    // 这里填被邀请者收到邀请后的回调通知
} // 被邀请者收到邀请后的回调通知
- (void)zim:(ZIM *)zim
    callInvitationReceived:(ZIMCallInvitationReceivedInfo *)info
                    callID:(NSString *)callID{
    // 这里填被邀请者收到邀请后的回调通知
} // 被邀请者收到邀请后的回调通知
// 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
void onCallInvitationReceived(zim::ZIM * zim, zim::ZIMCallInvitationReceivedInfo info,std::string callID) {
    ShowMsg(L"接收到邀请, 邀请者id:%s, callID: %s",info.inviter ,callID);
} // 被邀请者收到邀请后的回调通知
// 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
void onCallInvitationReceived(zim::ZIM * zim, zim::ZIMCallInvitationReceivedInfo info,std::string callID) {
    ShowMsg(L"接收到邀请, 邀请者id:%s, callID: %s",info.inviter ,callID);
} /** 被邀请者收到邀请后的回调通知 */
zim.on('callInvitationReceived', (zim: ZIM, data: ZIMEventOfCallInvitationReceivedResult) => {
})/** 被邀请者收到邀请后的回调通知 */
zim.on('callInvitationReceived', (zim: ZIM, data: ZIMEventOfCallInvitationReceivedResult) => {
})/** 被邀请者收到邀请后的回调通知 */
zim.onCallInvitationReceived((data) => {
})/** 被邀请者收到邀请后的回调通知 */
zim.onCallInvitationReceived((data) => {
})3 取消呼叫邀请
客户端 A 向客户端 B 发起呼叫邀请后、又取消邀请时,流程如下:

- 
客户端 A 发起呼叫邀请后,如果需要取消,可以调用 callCancel 接口,主动选择取消当前邀请。 说明在呼叫邀请成功创建后至其超时前,如果没有任何被叫用户接受,主叫用户主动登出或因心跳超时而掉线,也会导致呼叫邀请被取消。 
- 
邀请取消后,客户端 B 会收到 onCallInvitationCancelled 回调接口的相关通知。 
- 取消呼叫邀请
// 取消呼叫邀请
List<String> invitees;  // 被邀请人列表
invitees.add("421234");       // 被邀请人id
String callid = "12352435";        // callid
ZIMCallCancelConfig config = new ZIMCallCancelConfig();
ZIM.getInstance().callCancel(invitees, callid, config, new ZIMCallCancelSentCallback() {
    @Override
    public void onCallCancelSent(String callID, ArrayList<String> errorInvitees, ZIMError errorInfo) {
                
    }
});// 取消呼叫邀请
List<String> invitees;  // 被邀请人列表
invitees.add("421234");       // 被邀请人id
String callid = "12352435";        // callid
ZIMCallCancelConfig config = new ZIMCallCancelConfig();
ZIM.getInstance().callCancel(invitees, callid, config, new ZIMCallCancelSentCallback() {
    @Override
    public void onCallCancelSent(String callID, ArrayList<String> errorInvitees, ZIMError errorInfo) {
                
    }
});// 取消呼叫邀请
List<String> invitees;  // 被邀请人列表
invitees.add("421234");       // 被邀请人id
String callid = "12352435";        // callid
ZIMCallCancelConfig config = new ZIMCallCancelConfig();
ZIM
    .getInstance()
    !.callCancel(invitees, callID, callCancelConfig)
    .then((value) => {})
    .catchError((onError) {});// 取消呼叫邀请
List<String> invitees;  // 被邀请人列表
invitees.add("421234");       // 被邀请人id
String callid = "12352435";        // callid
ZIMCallCancelConfig config = new ZIMCallCancelConfig();
ZIM
    .getInstance()
    !.callCancel(invitees, callID, callCancelConfig)
    .then((value) => {})
    .catchError((onError) {});// 取消呼叫邀请
NSArray<NSString *> * invitees = @[@"421234"];  // 被邀请人列表
NSString* callid = @"12352435";  // callid
ZIMCallCancelConfig *callCancelConfig = [[ZIMCallCancelConfig alloc] init]; 
[zim callCancelWithInvitees:invitees callID:self.callID config:callCancelConfig callback:^(NSString * _Nonnull callID, NSArray<NSString *> * _Nonnull errorInvitees, ZIMError * _Nonnull errorInfo) {
    //这里填取消呼叫邀请后的回调
}];// 取消呼叫邀请
NSArray<NSString *> * invitees = @[@"421234"];  // 被邀请人列表
NSString* callid = @"12352435";  // callid
ZIMCallCancelConfig *callCancelConfig = [[ZIMCallCancelConfig alloc] init]; 
[zim callCancelWithInvitees:invitees callID:self.callID config:callCancelConfig callback:^(NSString * _Nonnull callID, NSArray<NSString *> * _Nonnull errorInvitees, ZIMError * _Nonnull errorInfo) {
    //这里填取消呼叫邀请后的回调
}];auto callcancel_callback = [=](std::vector<std::string> errorInvitees, zim::ZIMError errorInfo) {
    if (errorInfo.code != 0) {
        ShowMsg(L"发送取消呼叫邀请失败,错误码: %d",error_info.code);
    }    
    else {
        ShowMsg(L"发送取消呼叫邀请成功");
    }
}
// 取消呼叫邀请
std::vector<std::string> invitees;  // 被邀请人列表
invitees.push_back("421234");       // 被邀请人id
std::string callid = "12352435";        // callid
zim::ZIMCallCancelConfig config;
zim_->callCancel(invitees, callid, config, callcancel_callback);auto callcancel_callback = [=](std::vector<std::string> errorInvitees, zim::ZIMError errorInfo) {
    if (errorInfo.code != 0) {
        ShowMsg(L"发送取消呼叫邀请失败,错误码: %d",error_info.code);
    }    
    else {
        ShowMsg(L"发送取消呼叫邀请成功");
    }
}
// 取消呼叫邀请
std::vector<std::string> invitees;  // 被邀请人列表
invitees.push_back("421234");       // 被邀请人id
std::string callid = "12352435";        // callid
zim::ZIMCallCancelConfig config;
zim_->callCancel(invitees, callid, config, callcancel_callback);// 取消呼叫邀请
const callID = 'xxxx';
const invitees = ['xxxx'];  // 被邀请人ID列表
const config: ZIMCallCancelConfig = { extendedData: 'xxxx' };
zim.callCancel(invitees, callID, config)
    .then((res: ZIMCallCancelSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })// 取消呼叫邀请
const callID = 'xxxx';
const invitees = ['xxxx'];  // 被邀请人ID列表
const config: ZIMCallCancelConfig = { extendedData: 'xxxx' };
zim.callCancel(invitees, callID, config)
    .then((res: ZIMCallCancelSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })- 被邀请者收到取消邀请后的回调通知
// 被邀请者收到取消邀请后的回调通知
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    void onCallInvitationCancelled(ZIM zim, ZIMCallInvitationCancelledInfo info, String callID) {
    } 
});// 被邀请者收到取消邀请后的回调通知
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    void onCallInvitationCancelled(ZIM zim, ZIMCallInvitationCancelledInfo info, String callID) {
    } 
});//被邀请者收到取消邀请后的回调通知
ZIMEventHandler.onCallInvitationCancelled = (zim, info, callID) {
    
};//被邀请者收到取消邀请后的回调通知
ZIMEventHandler.onCallInvitationCancelled = (zim, info, callID) {
    
};// 被邀请者收到取消邀请后的回调通知
- (void)zim:(ZIM *)zim
    callInvitationCancelled:(ZIMCallInvitationCancelledInfo *)info
                    callID:(NSString *)callID{
    // 这里填被邀请者收到取消邀请后的回调通知
}// 被邀请者收到取消邀请后的回调通知
- (void)zim:(ZIM *)zim
    callInvitationCancelled:(ZIMCallInvitationCancelledInfo *)info
                    callID:(NSString *)callID{
    // 这里填被邀请者收到取消邀请后的回调通知
}// 被邀请者收到取消邀请后的回调通知
void onCallInvitationCancelled(zim::ZIM * zim, zim::ZIMCallInvitationCancelledInfo info,std::string callID) {
    ShowMsg(L"接收到取消邀请, 邀请者id:%s, callID: %s",info.inviter ,callID);
}// 被邀请者收到取消邀请后的回调通知
void onCallInvitationCancelled(zim::ZIM * zim, zim::ZIMCallInvitationCancelledInfo info,std::string callID) {
    ShowMsg(L"接收到取消邀请, 邀请者id:%s, callID: %s",info.inviter ,callID);
}// 被邀请者收到取消邀请后的回调通知
zim.on('callInvitationCancelled',(zim: ZIM, data: ZIMEventOfCallInvitationCancelledResult) => {
})// 被邀请者收到取消邀请后的回调通知
zim.on('callInvitationCancelled',(zim: ZIM, data: ZIMEventOfCallInvitationCancelledResult) => {
})// 被邀请者收到取消邀请后的回调通知
zim.onCallInvitationCancelled((data) => {
})// 被邀请者收到取消邀请后的回调通知
zim.onCallInvitationCancelled((data) => {
})4 接受呼叫邀请
客户端 B 收到客户端 A 的呼叫邀请后,选择接受邀请时,流程如下:

- 客户端 B 收到客户端 A 发来的呼叫邀请后,通过调用 callAccept 接口,接受该邀请。
- 客户端 B 接受邀请后,客户端 A 可以通过 onCallUserStateChanged 回调接口,收到相关通知。如果是在多人呼叫中,则所有现有呼叫成员都可通过此回调收到相关通知。
- 接受呼叫邀请
String callid = "12352435";        // callid
ZIMCallAcceptConfig config = new ZIMCallAcceptConfig();
ZIM.getInstance().callAccept(callid, config, new ZIMCallAcceptanceSentCallback() {
    @Override
    public void onCallAcceptanceSent(String callID, ZIMError errorInfo) {
                
    }
});String callid = "12352435";        // callid
ZIMCallAcceptConfig config = new ZIMCallAcceptConfig();
ZIM.getInstance().callAccept(callid, config, new ZIMCallAcceptanceSentCallback() {
    @Override
    public void onCallAcceptanceSent(String callID, ZIMError errorInfo) {
                
    }
});ZIMCallAcceptConfig callAcceptConfig = ZIMCallAcceptConfig();
ZIM
    .getInstance()
    !.callAccept(callID, callAcceptConfig)
    .then((value) => {})
    .catchError((onError) {});ZIMCallAcceptConfig callAcceptConfig = ZIMCallAcceptConfig();
ZIM
    .getInstance()
    !.callAccept(callID, callAcceptConfig)
    .then((value) => {})
    .catchError((onError) {});// 接受呼叫邀请
NSString* callid = @"12352435";  // callid
ZIMCallAcceptConfig*callAcceptConfig = [[ZIMCallAcceptConfig alloc] init]; 
[zim callAcceptWithCallID:self.callID config:callAcceptConfig callback:^(NSString * _Nonnull callID, ZIMError * _Nonnull errorInfo) {
    // 这里填接受呼叫邀请后的回调
}];
[zim callAcceptWithCallID:callid config:callAcceptConfig  callback:^(ZIMError *errorInfo){
    // 这里填接受呼叫邀请后的回调
}];// 接受呼叫邀请
NSString* callid = @"12352435";  // callid
ZIMCallAcceptConfig*callAcceptConfig = [[ZIMCallAcceptConfig alloc] init]; 
[zim callAcceptWithCallID:self.callID config:callAcceptConfig callback:^(NSString * _Nonnull callID, ZIMError * _Nonnull errorInfo) {
    // 这里填接受呼叫邀请后的回调
}];
[zim callAcceptWithCallID:callid config:callAcceptConfig  callback:^(ZIMError *errorInfo){
    // 这里填接受呼叫邀请后的回调
}];// 接受呼叫邀请
auto callaccept_callback = [=](zim::ZIMError errorInfo) {
    if (errorInfo.code != 0) {
        ShowMsg(L"接受呼叫邀请失败,错误码: %d", error_info.code);
    }    
    else {
        ShowMsg(L"接受呼叫邀请成功");
    }
}
std::string callid = "12352435";        // callid
zim::ZIMCallAcceptConfig config;
zim_->callAccept(callid, config, callaccept_callback);// 接受呼叫邀请
auto callaccept_callback = [=](zim::ZIMError errorInfo) {
    if (errorInfo.code != 0) {
        ShowMsg(L"接受呼叫邀请失败,错误码: %d", error_info.code);
    }    
    else {
        ShowMsg(L"接受呼叫邀请成功");
    }
}
std::string callid = "12352435";        // callid
zim::ZIMCallAcceptConfig config;
zim_->callAccept(callid, config, callaccept_callback);// 接受呼叫邀请
const callID = 'xxxx';
const config: ZIMCallAcceptConfig = { extendedData: 'xxxx' }; 
zim.callAccept(callID, config)
    .then((res: ZIMCallAcceptanceSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })// 接受呼叫邀请
const callID = 'xxxx';
const config: ZIMCallAcceptConfig = { extendedData: 'xxxx' }; 
zim.callAccept(callID, config)
    .then((res: ZIMCallAcceptanceSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })- 呼叫成员收到有用户接受呼叫邀请的通知
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID) {
    // 所有状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户接受呼叫邀请的通知
    }
});ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID) {
    // 所有状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户接受呼叫邀请的通知
    }
});ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户接受呼叫邀请的通知
};ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户接受呼叫邀请的通知
};-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户接受呼叫邀请的通知
}-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户接受呼叫邀请的通知
}// 呼叫成员收到有用户接受呼叫邀请的通知
void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info,
                                        const std::string & callID){
    // 所有状态为 “Inviting”、“Received” 和 “Accepted” 的用户可在此处收到有用户接受呼叫邀请的通知
}// 呼叫成员收到有用户接受呼叫邀请的通知
void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info,
                                        const std::string & callID){
    // 所有状态为 “Inviting”、“Received” 和 “Accepted” 的用户可在此处收到有用户接受呼叫邀请的通知
}// 邀请者接受邀请后的回调通知
zim.on('callUserStateChanged', (zim: ZIM, info: ZIMEventOfCallUserStateChangedResult) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 1 表示接受,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 1) {
            // 您的业务逻辑
        } 
    });
})// 邀请者接受邀请后的回调通知
zim.on('callUserStateChanged', (zim: ZIM, info: ZIMEventOfCallUserStateChangedResult) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 1 表示接受,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 1) {
            // 您的业务逻辑
        } 
    });
})// 邀请者接受邀请后的回调通知
zim.onCallUserStateChanged((info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 1 表示接受,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 1) {
            // 您的业务逻辑
        } 
    });
})// 邀请者接受邀请后的回调通知
zim.onCallUserStateChanged((info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 1 表示接受,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 1) {
            // 您的业务逻辑
        } 
    });
})5 拒绝呼叫邀请
客户端 B 收到客户端 A 的呼叫邀请后,选择拒绝邀请时,流程如下:

- 客户端 B 收到客户端 A 发来的呼叫邀请后,通过调用 callReject 接口,拒绝该邀请。
- 客户端 B 拒绝邀请后,客户端 A 可以通过 onCallUserStateChanged 回调接口,收到相关通知。如果是在多人呼叫中,则所有现有呼叫成员都可通过此回调收到相关通知。
- 拒绝呼叫邀请
String callid = "12352435";        // callid
ZIMCallRejectConfig config = new ZIMCallRejectConfig();
ZIM.getInstance().callReject(callid, config, new ZIMCallRejectionSentCallback() {
    @Override
    public void onCallRejectionSent(String callID, ZIMError errorInfo) {
                
    }
});String callid = "12352435";        // callid
ZIMCallRejectConfig config = new ZIMCallRejectConfig();
ZIM.getInstance().callReject(callid, config, new ZIMCallRejectionSentCallback() {
    @Override
    public void onCallRejectionSent(String callID, ZIMError errorInfo) {
                
    }
});String callID = "12352435";        // callID
ZIMCallRejectConfig rejectConfig = ZIMCallRejectConfig();
ZIM.getInstance()!.callReject(callID, rejectConfig).then((value) => {}).catchError((onError){});String callID = "12352435";        // callID
ZIMCallRejectConfig rejectConfig = ZIMCallRejectConfig();
ZIM.getInstance()!.callReject(callID, rejectConfig).then((value) => {}).catchError((onError){});// 拒绝呼叫邀请
NSString* callid = @"12352435";  // callid
ZIMCallRejectConfig* callRejectConfig = [[ZIMCallRejectConfig alloc] init]; 
[zim callRejectWithCallID:self.callID config:callRejectConfig callback:^(NSString * _Nonnull callID, ZIMError * _Nonnull errorInfo) {
    // 这里填拒绝呼叫邀请后的回调
}];// 拒绝呼叫邀请
NSString* callid = @"12352435";  // callid
ZIMCallRejectConfig* callRejectConfig = [[ZIMCallRejectConfig alloc] init]; 
[zim callRejectWithCallID:self.callID config:callRejectConfig callback:^(NSString * _Nonnull callID, ZIMError * _Nonnull errorInfo) {
    // 这里填拒绝呼叫邀请后的回调
}];// 拒绝呼叫邀请
auto callreject_callback = [=](zim::ZIMError errorInfo) {
    if (errorInfo.code != 0) {
        ShowMsg(L"拒绝呼叫邀请失败,错误码: %d",error_info.code);
    }    
    else {
        ShowMsg(L"拒绝呼叫邀请成功");
    }
}
std::string callid = "12352435";        // callid
zim::ZIMCallRejectConfig config;
zim_->callAccept(callid, config, callreject_callback );// 拒绝呼叫邀请
auto callreject_callback = [=](zim::ZIMError errorInfo) {
    if (errorInfo.code != 0) {
        ShowMsg(L"拒绝呼叫邀请失败,错误码: %d",error_info.code);
    }    
    else {
        ShowMsg(L"拒绝呼叫邀请成功");
    }
}
std::string callid = "12352435";        // callid
zim::ZIMCallRejectConfig config;
zim_->callAccept(callid, config, callreject_callback );// 拒绝呼叫邀请
const callID = 'xxxx';
const config: ZIMCallRejectConfig = { extendedData: 'xxxx' }; 
zim.callReject(callID, config)
    .then((res: ZIMCallRejectionSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })// 拒绝呼叫邀请
const callID = 'xxxx';
const config: ZIMCallRejectConfig = { extendedData: 'xxxx' }; 
zim.callReject(callID, config)
    .then((res: ZIMCallRejectionSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })- 呼叫成员收到有用户拒绝呼叫邀请的通知
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID) {
        // 所有状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户拒绝呼叫邀请的通知
    }
});ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID) {
        // 所有状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户拒绝呼叫邀请的通知
    }
});ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户拒绝呼叫邀请的通知
};ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户拒绝呼叫邀请的通知
};-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户拒绝呼叫邀请的通知
}-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户拒绝呼叫邀请的通知
}// 呼叫成员收到有用户拒绝呼叫邀请的通知
void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info,
                            const std::string & callID){
    // 所有用户状态为 “Inviting”、“Received” 和 “Accepted” 的用户可在此处收到有用户拒绝呼叫邀请的通知
}// 呼叫成员收到有用户拒绝呼叫邀请的通知
void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info,
                            const std::string & callID){
    // 所有用户状态为 “Inviting”、“Received” 和 “Accepted” 的用户可在此处收到有用户拒绝呼叫邀请的通知
}// 邀请者拒绝邀请后的回调通知
zim.on('callUserStateChanged', (zim: ZIM, info: ZIMEventOfCallUserStateChangedResult) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 2 表示拒绝,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 2) {
            // 您的业务逻辑
        }        
    });
})// 邀请者拒绝邀请后的回调通知
zim.on('callUserStateChanged', (zim: ZIM, info: ZIMEventOfCallUserStateChangedResult) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 2 表示拒绝,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 2) {
            // 您的业务逻辑
        }        
    });
})// 邀请者拒绝邀请后的回调通知
zim.onCallUserStateChanged((info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 2 表示拒绝,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 2) {
            // 您的业务逻辑
        }        
    });
})// 邀请者拒绝邀请后的回调通知
zim.onCallUserStateChanged((info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 2 表示拒绝,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 2) {
            // 您的业务逻辑
        }        
    });
})6 超时未响应呼叫邀请
客户端 B 收到客户端 A 的呼叫邀请后,客户端 B 长时间未响应时,流程如下:

- 客户端 A(邀请者)通过 onCallUserStateChanged 回调接口,收到邀请超时、客户端未响应的通知。如果是在多人呼叫中,则所有现有呼叫成员都可通过此回调收到相关通知。
- 客户端 B(被邀请者)通过 onCallInvitationTimeout 回调接口,收到邀请超时、自己未响应的通知。
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID){
        // 所有状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户呼叫邀请超时的通知
    }
    @Override
    public void onCallInvitationTimeout(ZIM zim, String callID) {
    // 被邀请者响应超时后,“被邀请者”收到的回调通知,超时时间单位:秒
    }     
});ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID){
        // 所有状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户呼叫邀请超时的通知
    }
    @Override
    public void onCallInvitationTimeout(ZIM zim, String callID) {
    // 被邀请者响应超时后,“被邀请者”收到的回调通知,超时时间单位:秒
    }     
});- Callback received by the inviter after the invitee did not response within the timeout period.
// 被邀请者响应超时后,“邀请者”收到的回调通知
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户超时的通知
};// 被邀请者响应超时后,“邀请者”收到的回调通知
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户超时的通知
};- 被邀请者响应超时后,“被邀请者”收到的回调通知
// 被邀请者响应超时后,“被邀请者”收到的回调通知,超时时间单位:秒
ZIMEventHandler.onCallInvitationTimeout = (ZIM zim, ZIMCallInvitationTimeoutInfo info, String callID) {
    
};// 被邀请者响应超时后,“被邀请者”收到的回调通知,超时时间单位:秒
ZIMEventHandler.onCallInvitationTimeout = (ZIM zim, ZIMCallInvitationTimeoutInfo info, String callID) {
    
};- 被邀请者响应超时后,“邀请者”收到的回调通知
// 被邀请者响应超时后,“被邀请者”收到的回调通知
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户接受呼叫邀请的通知
}// 被邀请者响应超时后,“被邀请者”收到的回调通知
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    // 所有用户状态为“Inviting”、“Accepted“和“Received”的用户可在此处收到有用户接受呼叫邀请的通知
}- 被邀请者响应超时后,“被邀请者”收到的回调通知
// 被邀请者响应超时后,“被邀请者”收到的回调通知
-(void)zim:(ZIM *)zim callInvitationTimeout:(NSString *)callID {
    // 这里填被邀请者响应超时后,“被邀请者”收到的回调通知, 超时时间单位:秒
}// 被邀请者响应超时后,“被邀请者”收到的回调通知
-(void)zim:(ZIM *)zim callInvitationTimeout:(NSString *)callID {
    // 这里填被邀请者响应超时后,“被邀请者”收到的回调通知, 超时时间单位:秒
}// 被邀请者响应超时后,“邀请者”收到的回调通知, 超时时间单位:秒
void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info,
                            const std::string & callID){
}// 被邀请者响应超时后,“邀请者”收到的回调通知, 超时时间单位:秒
void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info,
                            const std::string & callID){
}- 被邀请者响应超时后,“被邀请者”收到的回调通知
// 被邀请者响应超时后,“被邀请者”收到的回调通知, 超时时间单位:秒
void onCallInvitationTimeout(zim::ZIM * zim,std::string callID) {
    ShowMsg(L"呼叫邀请超时,callID: %s",callID);
}// 被邀请者响应超时后,“被邀请者”收到的回调通知, 超时时间单位:秒
void onCallInvitationTimeout(zim::ZIM * zim,std::string callID) {
    ShowMsg(L"呼叫邀请超时,callID: %s",callID);
}- 邀请者收到的回调:
zim.on('callUserStateChanged', (zim: ZIM, info: ZIMEventOfCallUserStateChangedResult) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 6 表示超时,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 6) {
            // 您的业务逻辑
        }
    });
})zim.on('callUserStateChanged', (zim: ZIM, info: ZIMEventOfCallUserStateChangedResult) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 6 表示超时,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 6) {
            // 您的业务逻辑
        }
    });
})- 被邀请者收到的回调:
// 被邀请者响应超时后,“被邀请者”收到的回调通知,超时时间单位:秒
zim.on('callInvitationTimeout', (zim: ZIM, data: ZIMEventOfCallInvitationTimeoutResult) => {
})// 被邀请者响应超时后,“被邀请者”收到的回调通知,超时时间单位:秒
zim.on('callInvitationTimeout', (zim: ZIM, data: ZIMEventOfCallInvitationTimeoutResult) => {
})- 邀请者收到的回调:
zim.onCallUserStateChanged((info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 6 表示超时,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 6) {
            // 您的业务逻辑
        }
    });
})zim.onCallUserStateChanged((info) => {
    // 相关的 callID
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 6 表示超时,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 6) {
            // 您的业务逻辑
        }
    });
})- 被邀请者收到的回调:
// 被邀请者响应超时后,“被邀请者”收到的回调通知,超时时间单位:秒
zim.onCallInvitationTimeout(data) => {
})// 被邀请者响应超时后,“被邀请者”收到的回调通知,超时时间单位:秒
zim.onCallInvitationTimeout(data) => {
})进阶模式
如果您想要实现更为丰富的用户状态场景,比如多人呼叫邀请业务场景,可以参考本节内容实现进阶模式的呼叫邀请。
发起进阶模式的呼叫邀请后,呼叫邀请的生命周期延长至用户主动调用 callEnd 接口结束呼叫。在结束呼叫之前,用户还可以实现在呼叫中继续邀请他人以及退出呼叫的功能。
发起进阶模式的呼叫邀请
开发者在调用 callInvite 接口时主动设置模式为进阶模式,才能发起进阶模式的呼叫邀请。
/** 向用户发送呼叫邀请 - 进阶模式 */
// 发送呼叫邀请
List<String> invitees;  // 被邀请人列表
invitees.add("421234");       // 被邀请人id
ZIMCallInviteConfig config = new ZIMCallInviteConfig(); 
config.timeout = 200; // 邀请超时时间,单位为秒,范围 1-600 
//  mode 为呼叫邀请模式,ADVANCED 表示进阶模式。
config.mode = ADVANCED;
// (可选)需要向离线用户发起呼叫邀请时填写
ZIMPushConfig pushConfig = new ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;
  
zim.callInvite(invitees, config, new ZIMCallInvitationSentCallback() {
    @Override
    public void onCallInvitationSent(String callID, ZIMCallInvitationSentInfo info, ZIMError errorInfo) {
        // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    }
 });/** 向用户发送呼叫邀请 - 进阶模式 */
// 发送呼叫邀请
List<String> invitees;  // 被邀请人列表
invitees.add("421234");       // 被邀请人id
ZIMCallInviteConfig config = new ZIMCallInviteConfig(); 
config.timeout = 200; // 邀请超时时间,单位为秒,范围 1-600 
//  mode 为呼叫邀请模式,ADVANCED 表示进阶模式。
config.mode = ADVANCED;
// (可选)需要向离线用户发起呼叫邀请时填写
ZIMPushConfig pushConfig = new ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;
  
zim.callInvite(invitees, config, new ZIMCallInvitationSentCallback() {
    @Override
    public void onCallInvitationSent(String callID, ZIMCallInvitationSentInfo info, ZIMError errorInfo) {
        // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    }
 });// 向用户发送呼叫邀请 - 进阶模式
List<String> invitees = ["421234"];  // 被邀请人 ID 列表
  
ZIMCallInviteConfig config = ZIMCallInviteConfig();
config.timeout = 200; // 邀请超时时间,单位为秒,范围 1-600
//  mode 为呼叫邀请模式,advanced 表示进阶模式。
config.mode = ZIMCallInvitationMode.advanced;
// (可选)需要向离线用户发起呼叫邀请时填写
ZIMPushConfig pushConfig = ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;
ZIM.getInstance()!.callInvite(invitees, config).then((ZIMCallInvitationSentResult result){
    // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
});// 向用户发送呼叫邀请 - 进阶模式
List<String> invitees = ["421234"];  // 被邀请人 ID 列表
  
ZIMCallInviteConfig config = ZIMCallInviteConfig();
config.timeout = 200; // 邀请超时时间,单位为秒,范围 1-600
//  mode 为呼叫邀请模式,advanced 表示进阶模式。
config.mode = ZIMCallInvitationMode.advanced;
// (可选)需要向离线用户发起呼叫邀请时填写
ZIMPushConfig pushConfig = ZIMPushConfig();
pushConfig.title = "your title";
pushConfig.content = "your content";
pushConfig.payload = "your payload";
config.pushConfig = pushConfig;
ZIM.getInstance()!.callInvite(invitees, config).then((ZIMCallInvitationSentResult result){
    // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
});// 向用户发送呼叫邀请 - 进阶模式
NSArray<NSString *> * invitees = @[@"421234"];  // 被邀请人列表
ZIMCallInviteConfig *callInviteConfig = [[ZIMCallInviteConfig alloc] init]; 
//  mode 为呼叫邀请模式,ZIMCallInvitationModeAdvanced 表示进阶模式。
callInviteConfig.mode = ZIMCallInvitationModeAdvanced;
// 设置邀请的超时时间
callInviteConfig.timeout = 200;
//(可选)需要向离线用户发起呼叫邀请并推送相关离线通知时填写
ZIMPushConfig *pushConfig = [[ZIMPushConfig alloc] init];
pushConfig.title = @"your title";
pushConfig.content = @"your content";
pushConfig.payload = @"your payload";
callInviteConfig.pushConfig = pushConfig;
[zim callInviteWithInvitees:invitees config:callInviteConfig callback:^(NSString *callID, ZIMCallInvitationSentInfo *info,ZIMError *errorInfo){
    // 这里填发送呼叫邀请后的回调
    // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
}];// 向用户发送呼叫邀请 - 进阶模式
NSArray<NSString *> * invitees = @[@"421234"];  // 被邀请人列表
ZIMCallInviteConfig *callInviteConfig = [[ZIMCallInviteConfig alloc] init]; 
//  mode 为呼叫邀请模式,ZIMCallInvitationModeAdvanced 表示进阶模式。
callInviteConfig.mode = ZIMCallInvitationModeAdvanced;
// 设置邀请的超时时间
callInviteConfig.timeout = 200;
//(可选)需要向离线用户发起呼叫邀请并推送相关离线通知时填写
ZIMPushConfig *pushConfig = [[ZIMPushConfig alloc] init];
pushConfig.title = @"your title";
pushConfig.content = @"your content";
pushConfig.payload = @"your payload";
callInviteConfig.pushConfig = pushConfig;
[zim callInviteWithInvitees:invitees config:callInviteConfig callback:^(NSString *callID, ZIMCallInvitationSentInfo *info,ZIMError *errorInfo){
    // 这里填发送呼叫邀请后的回调
    // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
}];// 向在线用户发送呼叫邀请 - 进阶模式
vector<std::string> invitees; // 被邀请人ID列表
    
// 邀请超时时间,单位为秒,范围 1 - 600
// mode 为呼叫邀请模式,ZIM_INVITATION_MODE_ADVANCED 表示进阶模式。
ZIMCallInviteConfig config = ZIMCallInviteConfig();
config.mode = ZIM_INVITATION_MODE_ADVANCED;
config.timeout = 90;
ZIM::getInstance()->callInvite(invitees, config, [](const std::string &callID, const ZIMCallInvitationSentInfo &info, const ZIMError &errorInfo){
  if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
    // 操作成功
    // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
  }else{
    // 操作失败
  }
});// 向在线用户发送呼叫邀请 - 进阶模式
vector<std::string> invitees; // 被邀请人ID列表
    
// 邀请超时时间,单位为秒,范围 1 - 600
// mode 为呼叫邀请模式,ZIM_INVITATION_MODE_ADVANCED 表示进阶模式。
ZIMCallInviteConfig config = ZIMCallInviteConfig();
config.mode = ZIM_INVITATION_MODE_ADVANCED;
config.timeout = 90;
ZIM::getInstance()->callInvite(invitees, config, [](const std::string &callID, const ZIMCallInvitationSentInfo &info, const ZIMError &errorInfo){
  if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
    // 操作成功
    // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
  }else{
    // 操作失败
  }
});/** 向在线用户发送呼叫邀请 - 进阶模式 */
const invitees = ['xxxx'];  // 被邀请人ID列表
const config: ZIMCallInviteConfig = { 
    //  呼叫邀请模式,1 表示进阶模式。
    mode: 1,
    // 邀请超时时间,单位为秒,范围 1 - 600
    timeout: 200, 
    extendedData: ''
};
zim.callInvite(invitees, config)
    .then((res: ZIMCallInvitationSentResult) => {
        const callID = res.callID;
        // 操作成功
        // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })/** 向在线用户发送呼叫邀请 - 进阶模式 */
const invitees = ['xxxx'];  // 被邀请人ID列表
const config: ZIMCallInviteConfig = { 
    //  呼叫邀请模式,1 表示进阶模式。
    mode: 1,
    // 邀请超时时间,单位为秒,范围 1 - 600
    timeout: 200, 
    extendedData: ''
};
zim.callInvite(invitees, config)
    .then((res: ZIMCallInvitationSentResult) => {
        const callID = res.callID;
        // 操作成功
        // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })除了发起外,呼叫邀请的进阶模式和普通模式在取消、接受、拒绝和超时未响应上没有差别。
呼叫中邀请
在创建进阶模式呼叫邀请后,状态为 Accepted 的用户可以调用 callingInvite 接口向不在本呼叫中的用户发起邀请。但是,同一个呼叫中的参与用户不能超过 10 人(含邀请创建用户)。
- 呼叫中邀请
// 呼叫中邀请
ArrayList<String> inviteesList = new ArrayList<>();
inviteesList.add("inviteesA");
inviteesList.add("inviteesB");
ZIMCallingInviteConfig inviteConfig = new ZIMCallingInviteConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance().callingInvite(inviteesList, callID, inviteConfig, new ZIMCallingInvitationSentCallback() {
    @Override
    public void onCallingInvitationSent(String callID, ZIMCallingInvitationSentInfo info, ZIMError errorInfo) {
        if(errorInfo.code != ZIMErrorCode.SUCCESS){
            //根据官网错误码表处理
        }
        //邀请成功后的业务逻辑
    }
});// 呼叫中邀请
ArrayList<String> inviteesList = new ArrayList<>();
inviteesList.add("inviteesA");
inviteesList.add("inviteesB");
ZIMCallingInviteConfig inviteConfig = new ZIMCallingInviteConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance().callingInvite(inviteesList, callID, inviteConfig, new ZIMCallingInvitationSentCallback() {
    @Override
    public void onCallingInvitationSent(String callID, ZIMCallingInvitationSentInfo info, ZIMError errorInfo) {
        if(errorInfo.code != ZIMErrorCode.SUCCESS){
            //根据官网错误码表处理
        }
        //邀请成功后的业务逻辑
    }
});- 呼叫成员收到正在邀请其他用户的通知
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID){
        // 所有用户状态为“呼叫中”和“已接受”的用户可在此处收到有用户被呼叫邀请的通知
    }
});ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID){
        // 所有用户状态为“呼叫中”和“已接受”的用户可在此处收到有用户被呼叫邀请的通知
    }
});// 呼叫中邀请
List<String> inviteesList = ["A","B"];
ZIMCallingInviteConfig inviteConfig = ZIMCallingInviteConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance()!.callingInvite(inviteesList, "callID", inviteConfig).then((value) {
    //邀请成功后的业务逻辑
}).catchError((onError) {
    //根据官网错误码表处理
});// 呼叫中邀请
List<String> inviteesList = ["A","B"];
ZIMCallingInviteConfig inviteConfig = ZIMCallingInviteConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance()!.callingInvite(inviteesList, "callID", inviteConfig).then((value) {
    //邀请成功后的业务逻辑
}).catchError((onError) {
    //根据官网错误码表处理
});- 呼叫成员收到正在邀请其他用户的通知
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
        // 所有用户状态为“inviting”,"received"和“accept”的用户可在此处收到有用户被呼叫邀请的通知
};ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
        // 所有用户状态为“inviting”,"received"和“accept”的用户可在此处收到有用户被呼叫邀请的通知
};// 呼叫中邀请
ZIMCallingInviteConfig *config = [[ZIMCallingInviteConfig alloc] init];
// callID 通过创建进阶呼叫邀请的回调获取
[[ZIM getInstance] callingInviteWithInvitees:@[@"invitees"] callID:self.callID config:config callback:^(NSString * _Nonnull callID, ZIMCallingInvitationSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code != ZIMErrorCodeSuccess){
        // 根据官网错误码表处理
        return;
    }
    // 邀请成功后的业务逻辑
}];// 呼叫中邀请
ZIMCallingInviteConfig *config = [[ZIMCallingInviteConfig alloc] init];
// callID 通过创建进阶呼叫邀请的回调获取
[[ZIM getInstance] callingInviteWithInvitees:@[@"invitees"] callID:self.callID config:config callback:^(NSString * _Nonnull callID, ZIMCallingInvitationSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code != ZIMErrorCodeSuccess){
        // 根据官网错误码表处理
        return;
    }
    // 邀请成功后的业务逻辑
}];- 呼叫成员收到正在邀请其他用户的通知
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    // 所有用户状态为“邀请中”和“已接受”的用户可以在此处收到正在呼叫邀请一名用户的通知
}-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    // 所有用户状态为“邀请中”和“已接受”的用户可以在此处收到正在呼叫邀请一名用户的通知
}// 呼叫中邀请
vector<std::string> invitees; // 被邀请人ID列表
ZIMCallingInviteConfig config = ZIMCallingInviteConfig();
ZIM::getInstance()->callingInvite(invitees, "callID", config, [](const std::string &callID, const ZIMCallingInvitationSentInfo &info,const ZIMError &errorInfo){
    if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
        // 邀请成功后的业务逻辑
    }else{
        // 根据官网错误码表处理
    }
});// 呼叫中邀请
vector<std::string> invitees; // 被邀请人ID列表
ZIMCallingInviteConfig config = ZIMCallingInviteConfig();
ZIM::getInstance()->callingInvite(invitees, "callID", config, [](const std::string &callID, const ZIMCallingInvitationSentInfo &info,const ZIMError &errorInfo){
    if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
        // 邀请成功后的业务逻辑
    }else{
        // 根据官网错误码表处理
    }
});- 呼叫成员收到正在邀请其他用户的通知
void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info,
                                        const std::string & callID){
    // 所有未退出、超时的成员可以在此处收到成员被呼叫邀请的通知
}void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info,
                                        const std::string & callID){
    // 所有未退出、超时的成员可以在此处收到成员被呼叫邀请的通知
}// 呼叫中邀请
const config: ZIMCallingInviteConfig = {};
const userList = [];
// callID 通过创建进阶模式呼叫邀请的回调获取。
zim.callingInvite(userList, 'callID', config)
    .then((res: ZIMCallingInvitationSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });// 呼叫中邀请
const config: ZIMCallingInviteConfig = {};
const userList = [];
// callID 通过创建进阶模式呼叫邀请的回调获取。
zim.callingInvite(userList, 'callID', config)
    .then((res: ZIMCallingInvitationSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });主动加入呼叫或切换设备
实现进阶模式呼叫邀请后,以下两种情况下,可以调用 callJoin 接口:
- 没有加入呼叫的用户希望加入呼叫。
- 对于呼叫外用户加入成功的场景,该用户的状态将流转为 accepted,此时呼叫中的所有用户收到 onCallUserStateChanged 的通知回调。
 
- 对于呼叫外用户加入成功的场景,该用户的状态将流转为 
- 多端登录用户使用设备 A 发起或接受邀请后,希望让其他设备成为新的主设备。
- 对于切换设备的场景,呼叫内其他用户无感知。
 
- 主设备,是指主动调用发起、接受或加入呼叫接口参与呼叫的设备。
- 只有主设备能感知呼叫邀请的变化,其他设备只能通过查询呼叫邀请列表来获取呼叫邀请内的数据。
// 主动加入呼叫或切换设备
ZIMCallJoinConfig config = new ZIMCallJoinConfig();
config.extendedData = "extendedData";
ZIM.getInstance().callJoin(callID, config, new ZIMCallJoinSentCallback() {
    @Override
    public onCallJoinSent(String callID, ZIMCallJoinSentInfo info, ZIMError errorInfo) {
        if(errorInfo.code == ZIMErrorCode.SUCCESS){
            // 加入成功后的业务逻辑
        } else{
            // 根据官网错误码表处理错误
        }
    }
});// 主动加入呼叫或切换设备
ZIMCallJoinConfig config = new ZIMCallJoinConfig();
config.extendedData = "extendedData";
ZIM.getInstance().callJoin(callID, config, new ZIMCallJoinSentCallback() {
    @Override
    public onCallJoinSent(String callID, ZIMCallJoinSentInfo info, ZIMError errorInfo) {
        if(errorInfo.code == ZIMErrorCode.SUCCESS){
            // 加入成功后的业务逻辑
        } else{
            // 根据官网错误码表处理错误
        }
    }
});// 主动加入呼叫或切换设备
ZIMCallJoinConfig joinConfig = ZIMCallJoinConfig();
joinConfig.extendedData = "extendedData";
ZIM.getInstance()?.callJoin('callID',joinConfig).then((result) => {
    // 加入成功后的业务逻辑
}).catchError((onError){
    // 根据官网错误码表处理错误
});// 主动加入呼叫或切换设备
ZIMCallJoinConfig joinConfig = ZIMCallJoinConfig();
joinConfig.extendedData = "extendedData";
ZIM.getInstance()?.callJoin('callID',joinConfig).then((result) => {
    // 加入成功后的业务逻辑
}).catchError((onError){
    // 根据官网错误码表处理错误
});// 主动加入呼叫或切换设备
ZIMCallJoinConfig *callJoinConfig = [[ZIMCallJoinConfig alloc] init];
callJoinConfig.extendedData = @"extendedData";
[[ZIM getInstance] callJoin:@"callID" config:callJoinConfig callback:^(NSString * _Nonnull callID, ZIMCallJoinSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code == ZIMErrorCodeSuccess){
          
    }else{
        // 根据官网错误码表处理错误
    }
}];// 主动加入呼叫或切换设备
ZIMCallJoinConfig *callJoinConfig = [[ZIMCallJoinConfig alloc] init];
callJoinConfig.extendedData = @"extendedData";
[[ZIM getInstance] callJoin:@"callID" config:callJoinConfig callback:^(NSString * _Nonnull callID, ZIMCallJoinSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code == ZIMErrorCodeSuccess){
          
    }else{
        // 根据官网错误码表处理错误
    }
}];// 主动加入呼叫或切换设备
zim::ZIMCallJoinConfig config;
config.extendedData = "extendedData";
ZIM::getInstance()->callJoin("callID", config, [=](const std::string &callID, const ZIMCallJoinSentInfo &info, const ZIMError &errorInfo){
    if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
        // 加入成功后的业务逻辑
    }else{
        // 根据官网错误码表处理错误
    }
});// 主动加入呼叫或切换设备
zim::ZIMCallJoinConfig config;
config.extendedData = "extendedData";
ZIM::getInstance()->callJoin("callID", config, [=](const std::string &callID, const ZIMCallJoinSentInfo &info, const ZIMError &errorInfo){
    if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
        // 加入成功后的业务逻辑
    }else{
        // 根据官网错误码表处理错误
    }
});// 主动加入呼叫或切换设备
const config: ZIMCallJoinConfig = { extendedData: 'callJoin extendedData' };
zim.callJoin('callID', config)
    .then((res: ZIMCallJoinSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });// 主动加入呼叫或切换设备
const config: ZIMCallJoinConfig = { extendedData: 'callJoin extendedData' };
zim.callJoin('callID', config)
    .then((res: ZIMCallJoinSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });退出呼叫
实现进阶模式呼叫邀请后,呼叫用户状态为 Accepted 的用户可调用 callQuit 接口退出呼叫。退出成功后,该用户的状态将流转为 quit,该用户和仍在呼叫中的其他用户都将会收到 onCallUserStateChanged 的通知回调。
- 退出呼叫
// 退出呼叫
ZIMCallQuitConfig config = new ZIMCallQuitConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance().callQuit(callID, config, new ZIMCallQuitSentCallback() {
    @Override
    public void onCallQuitSent(String callID, ZIMCallQuitSentInfo info, ZIMError errorInfo) {
        if(errorInfo.code == ZIMErrorCode.SUCCESS){
            // 退出成功后的业务逻辑
        }else {
            // 退出成功后的业务逻辑
        }
    }
});// 退出呼叫
ZIMCallQuitConfig config = new ZIMCallQuitConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance().callQuit(callID, config, new ZIMCallQuitSentCallback() {
    @Override
    public void onCallQuitSent(String callID, ZIMCallQuitSentInfo info, ZIMError errorInfo) {
        if(errorInfo.code == ZIMErrorCode.SUCCESS){
            // 退出成功后的业务逻辑
        }else {
            // 退出成功后的业务逻辑
        }
    }
});- 呼叫成员收到有用户退出呼叫的通知
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID){
        // // 退出用户本人和用户状态为 “inviting”, “received” 和 “accept” 的其他用户可在此处收到有用户退出呼叫的通知
    }
});  ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallUserStateChanged(ZIM zim, ZIMCallUserStateChangeInfo info, String callID){
        // // 退出用户本人和用户状态为 “inviting”, “received” 和 “accept” 的其他用户可在此处收到有用户退出呼叫的通知
    }
});  - 退出呼叫
// 退出呼叫
ZIMCallQuitConfig config = ZIMCallQuitConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance()!.callQuit("callID", config).then((value) {
    // 退出成功后的业务逻辑
}).catchError((onError){
    // 退出失败的业务逻辑
});// 退出呼叫
ZIMCallQuitConfig config = ZIMCallQuitConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance()!.callQuit("callID", config).then((value) {
    // 退出成功后的业务逻辑
}).catchError((onError){
    // 退出失败的业务逻辑
});- 呼叫成员收到有用户退出呼叫的通知
ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
        // 退出用户本人和用户状态为 “inviting”, “received” 和 “accept” 的其他用户可在此处收到有用户员退出呼叫的通知
}; ZIMEventHandler.onCallUserStateChanged = (ZIM zim, ZIMCallUserStateChangeInfo callUserStateChangeInfo, String callID){
        // 退出用户本人和用户状态为 “inviting”, “received” 和 “accept” 的其他用户可在此处收到有用户员退出呼叫的通知
}; // 退出呼叫
ZIMCallQuitConfig *config = [[ZIMCallQuitConfig alloc] init];
[[ZIM getInstance] callQuit:self.callID config:config callback:^(NSString * _Nonnull callID, ZIMCallQuitSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code == ZIMErrorCodeSuccess){
        // 退出成功后的业务逻辑
    }else{
        // 根据官网错误码表处理错误
    }
}];// 退出呼叫
ZIMCallQuitConfig *config = [[ZIMCallQuitConfig alloc] init];
[[ZIM getInstance] callQuit:self.callID config:config callback:^(NSString * _Nonnull callID, ZIMCallQuitSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code == ZIMErrorCodeSuccess){
        // 退出成功后的业务逻辑
    }else{
        // 根据官网错误码表处理错误
    }
}];- 呼叫成员收到有用户退出呼叫的通知
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    // 退出用户本人和状态为 “Inviting”、“Accepted“和“Received”的其他用户可以在此处收到有用户退出呼叫的通知
}-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    // 退出用户本人和状态为 “Inviting”、“Accepted“和“Received”的其他用户可以在此处收到有用户退出呼叫的通知
}- 退出呼叫
// 退出呼叫
ZIMCallQuitConfig config = ZIMCallQuitConfig();
ZIM::getInstance()->callQuit("callID", config, [](const std::string &callID, const ZIMCallQuitSentInfo &info, const ZIMError &errorInfo){
    if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
        // 退出成功后的业务逻辑
    }else{
        // 根据官网错误码表处理错误
    }
});// 退出呼叫
ZIMCallQuitConfig config = ZIMCallQuitConfig();
ZIM::getInstance()->callQuit("callID", config, [](const std::string &callID, const ZIMCallQuitSentInfo &info, const ZIMError &errorInfo){
    if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
        // 退出成功后的业务逻辑
    }else{
        // 根据官网错误码表处理错误
    }
});- 呼叫成员收到有用户退出呼叫的通知
void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info,
                                    const std::string & callID){
    // 退出用户本人和用户状态为 “inviting”, “received” 和 “accept” 的其他用户可在此处收到有用户员退出的通知
}void onCallUserStateChanged(ZIM * zim, const ZIMCallUserStateChangeInfo & info,
                                    const std::string & callID){
    // 退出用户本人和用户状态为 “inviting”, “received” 和 “accept” 的其他用户可在此处收到有用户员退出的通知
}- 退出呼叫
// 退出呼叫
const config: ZIMCallQuitConfig = { extendedData: 'callQuit extendedData' };
zim.callQuit('callID', config)
    .then((res: ZIMCallQuitSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });// 退出呼叫
const config: ZIMCallQuitConfig = { extendedData: 'callQuit extendedData' };
zim.callQuit('callID', config)
    .then((res: ZIMCallQuitSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });- 呼叫成员收到有用户退出呼叫的通知
// 退出用户本人和用户状态为 “inviting”, “received” 和 “accept” 的其他用户可在此处收到有用户员退出邀请的通知       
zim.on('callUserStateChanged', (zim: ZIM, info: ZIMEventOfCallUserStateChangedResult) => {
    // callID 通过创建进阶模式呼叫邀请的回调获取
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 7 表示退出,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 7) {
            // 您的业务逻辑
        }
        
    });
})// 退出用户本人和用户状态为 “inviting”, “received” 和 “accept” 的其他用户可在此处收到有用户员退出邀请的通知       
zim.on('callUserStateChanged', (zim: ZIM, info: ZIMEventOfCallUserStateChangedResult) => {
    // callID 通过创建进阶模式呼叫邀请的回调获取
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 7 表示退出,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 7) {
            // 您的业务逻辑
        }
        
    });
})- 退出呼叫
// 退出呼叫
const config: ZIMCallQuitConfig = { extendedData: 'callQuit extendedData' };
zim.callQuit('callID', config)
    .then((res: ZIMCallQuitSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });// 退出呼叫
const config: ZIMCallQuitConfig = { extendedData: 'callQuit extendedData' };
zim.callQuit('callID', config)
    .then((res: ZIMCallQuitSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });- 呼叫成员收到有用户退出呼叫的通知
// 退出用户本人和用户状态为 “inviting”, “received” 和 “accept” 的其他用户可在此处收到有用户员退出邀请的通知       
zim.onCallUserStateChanged((info) => {
    // callID 通过创建进阶模式呼叫邀请的回调获取
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 7 表示退出,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 7) {
            // 您的业务逻辑
        }
        
    });
})// 退出用户本人和用户状态为 “inviting”, “received” 和 “accept” 的其他用户可在此处收到有用户员退出邀请的通知       
zim.onCallUserStateChanged((info) => {
    // callID 通过创建进阶模式呼叫邀请的回调获取
    const changeCallID = info.callID;
    info.callUserList.forEach(userInfo => {
        // 状态变化用户的 userID、最新用户状态、透传字段(与用户该调用接受、拒绝、退出呼叫时携带的 extended data 一致)
        // state = 7 表示退出,具体可以参考枚举 ZIMCallUserState
        if (userInfo.state == 7) {
            // 您的业务逻辑
        }
        
    });
})结束呼叫
实现进阶模式呼叫邀请后,呼叫用户状态为 Accepted 的用户可调用 callEnd 接口结束呼叫。此后,所有人的状态保持不变,该呼叫的状态(callState)变为 end,状态为 Iniviting、Accepted 和 Received 的用户将会收到 onCallInvitationEnded 的通知回调。
- 结束呼叫
// 结束呼叫
ZIMCallEndConfig endConfig = new ZIMCallEndConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance().callEnd(callID, endConfig, new ZIMCallEndSentCallback() {
    @Override
    public void onCallEndSent(String callID, ZIMCallEndSentInfo info, ZIMError errorInfo) {
        if(errorInfo.code == ZIMErrorCode.SUCCESS){
            // 结束成功后的业务逻辑
        }else{
                    // 根据官网错误码表处理错误
                }
            }
        });// 结束呼叫
ZIMCallEndConfig endConfig = new ZIMCallEndConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance().callEnd(callID, endConfig, new ZIMCallEndSentCallback() {
    @Override
    public void onCallEndSent(String callID, ZIMCallEndSentInfo info, ZIMError errorInfo) {
        if(errorInfo.code == ZIMErrorCode.SUCCESS){
            // 结束成功后的业务逻辑
        }else{
                    // 根据官网错误码表处理错误
                }
            }
        });- 呼叫成员收到呼叫结束的通知
ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallInvitationEnded(ZIM zim, ZIMCallInvitationEndedInfo info, String callID) {
        super.onCallInvitationEnded(zim, info, callID);
    }
});ZIM.getInstance().setEventHandler(new ZIMEventHandler() {
    @Override
    public void onCallInvitationEnded(ZIM zim, ZIMCallInvitationEndedInfo info, String callID) {
        super.onCallInvitationEnded(zim, info, callID);
    }
});// 结束呼叫
ZIMCallEndConfig config = ZIMCallEndConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance()!.callEnd("callID", config).then((value) {
    // 结束成功后的业务逻辑
}).catchError((onError){
    // 根据官网错误码表处理错误
});// 结束呼叫
ZIMCallEndConfig config = ZIMCallEndConfig();
// callID 通过创建进阶模式呼叫邀请的回调获取
ZIM.getInstance()!.callEnd("callID", config).then((value) {
    // 结束成功后的业务逻辑
}).catchError((onError){
    // 根据官网错误码表处理错误
});- 呼叫成员收到呼叫结束的通知
ZIMEventHandler.onCallInvitationEnded = (ZIM zim, ZIMCallInvitationEndedInfo info, String callID) {
    
};ZIMEventHandler.onCallInvitationEnded = (ZIM zim, ZIMCallInvitationEndedInfo info, String callID) {
    
};// 结束呼叫
ZIMCallEndConfig *config = [[ZIMCallEndConfig alloc] init];
[[ZIM getInstance] callEnd:self.callID config:config callback:^(NSString * _Nonnull callID, ZIMCallEndedSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code == ZIMErrorCodeSuccess){
        // 结束成功后的业务逻辑
    }else{
        // 根据官网错误码表处理错误
    }
}];// 结束呼叫
ZIMCallEndConfig *config = [[ZIMCallEndConfig alloc] init];
[[ZIM getInstance] callEnd:self.callID config:config callback:^(NSString * _Nonnull callID, ZIMCallEndedSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code == ZIMErrorCodeSuccess){
        // 结束成功后的业务逻辑
    }else{
        // 根据官网错误码表处理错误
    }
}];- 呼叫成员收到呼叫结束的通知
- (void)zim:(ZIM *)zim callInvitationEnded:(ZIMCallInvitationEndedInfo *)info callID:(NSString *)callID{
    // 所有用户状态为 “Inviting”、“Accepted“ 和 “Received” 的用户会收到呼叫结束的通知
}- (void)zim:(ZIM *)zim callInvitationEnded:(ZIMCallInvitationEndedInfo *)info callID:(NSString *)callID{
    // 所有用户状态为 “Inviting”、“Accepted“ 和 “Received” 的用户会收到呼叫结束的通知
}// 结束呼叫
ZIMCallEndConfig config = ZIMCallEndConfig();
ZIM::getInstance()->callEnd("callID", config, [](const std::string &callID, const ZIMCallEndedSentInfo &info, const ZIMError &errorInfo){
        if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
            // 退出成功后的业务逻辑
        }else{
            // 根据官网错误码表处理错误
        }
});// 结束呼叫
ZIMCallEndConfig config = ZIMCallEndConfig();
ZIM::getInstance()->callEnd("callID", config, [](const std::string &callID, const ZIMCallEndedSentInfo &info, const ZIMError &errorInfo){
        if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
            // 退出成功后的业务逻辑
        }else{
            // 根据官网错误码表处理错误
        }
});- 呼叫成员收到呼叫结束的通知
void onCallInvitationEnded(ZIM * /*zim*/, const ZIMCallInvitationEndedInfo & /*info*/,
                                    const std::string & /*callID*/) {
    // 所有状态为 “Inviting”、“Received” 和 “Accepted” 的成员可以在此处收到呼叫结束的通知
}void onCallInvitationEnded(ZIM * /*zim*/, const ZIMCallInvitationEndedInfo & /*info*/,
                                    const std::string & /*callID*/) {
    // 所有状态为 “Inviting”、“Received” 和 “Accepted” 的成员可以在此处收到呼叫结束的通知
}// 结束呼叫
const config: ZIMCallEndConfig = { extendedData: 'callEnd extendedData' };
// callID 通过创建进阶模式呼叫邀请的回调获取
zim.callEnd('callID', config)
    .then((res: ZIMCallEndSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });// 结束呼叫
const config: ZIMCallEndConfig = { extendedData: 'callEnd extendedData' };
// callID 通过创建进阶模式呼叫邀请的回调获取
zim.callEnd('callID', config)
    .then((res: ZIMCallEndSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });- 呼叫成员收到呼叫结束的通知
// 呼叫成员收到的回调通知
zim.on('callInvitationEnded', (zim: ZIM, info: ZIMEventOfCallInvitationEndedResult) => {
    // console.log('callInvitationEnded', info)
})// 呼叫成员收到的回调通知
zim.on('callInvitationEnded', (zim: ZIM, info: ZIMEventOfCallInvitationEndedResult) => {
    // console.log('callInvitationEnded', info)
})// 结束呼叫
const config: ZIMCallEndConfig = { extendedData: 'callEnd extendedData' };
// callID 通过创建进阶模式呼叫邀请的回调获取
zim.callEnd('callID', config)
    .then((res: ZIMCallEndSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });// 结束呼叫
const config: ZIMCallEndConfig = { extendedData: 'callEnd extendedData' };
// callID 通过创建进阶模式呼叫邀请的回调获取
zim.callEnd('callID', config)
    .then((res: ZIMCallEndSentResult) => {
        // 操作成功
    })
    .catch((err: ZIMError) => {
        // 操作失败
    });- 呼叫成员收到呼叫结束的通知
// 呼叫成员收到的回调通知
zim.onCallInvitationEnded((info) => {
    // console.log('onCallInvitationEnded', info)
})// 呼叫成员收到的回调通知
zim.onCallInvitationEnded((info) => {
    // console.log('onCallInvitationEnded', info)
})呼叫邀请离线推送
- (可选)如需实现呼叫邀请离线推送,请参考下表。
| 呼叫邀请离线推送发起端 | 呼叫邀请离线推送接收端 | 接收端配置参考文档 | 
|---|---|---|
| 
 | 
 | 
更多功能
检测邀请是否送达
如需让邀请内在线用户了解其他用户是否收到邀请,从而实现相关业务逻辑,请在发起呼叫邀请时,将 ZIMCallInviteConfig 中的 enableNotReceivedCheck 修改为 true,从而开始检测邀请是否送达。
ZIMCallInviteConfig config = new ZIMCallInviteConfig();
//开启暂未送达检测
config.enableNotReceivedCheck = true;
// 发起呼叫邀请相关代码ZIMCallInviteConfig config = new ZIMCallInviteConfig();
//开启暂未送达检测
config.enableNotReceivedCheck = true;
// 发起呼叫邀请相关代码ZIMCallInviteConfig inviteConfig = ZIMCallinviteConfig();
// 开启暂未送达检测
inviteConfig.enableNotReceivedCheck = true;
// 发起呼叫邀请相关代码ZIMCallInviteConfig inviteConfig = ZIMCallinviteConfig();
// 开启暂未送达检测
inviteConfig.enableNotReceivedCheck = true;
// 发起呼叫邀请相关代码ZIMCallInviteConfig *inviteConfig = [[ZIMCallInviteConfig alloc] init];
//开启暂未送达检测
inviteConfig.enableNotReceivedCheck = YES;
// 发起呼叫邀请相关代码ZIMCallInviteConfig *inviteConfig = [[ZIMCallInviteConfig alloc] init];
//开启暂未送达检测
inviteConfig.enableNotReceivedCheck = YES;
// 发起呼叫邀请相关代码ZIMCallInviteConfig inviteConfig = ZIMCallinviteConfig();
// 开启暂未送达检测
inviteConfig.enableNotReceivedCheck = true;
// 发起呼叫邀请相关代码ZIMCallInviteConfig inviteConfig = ZIMCallinviteConfig();
// 开启暂未送达检测
inviteConfig.enableNotReceivedCheck = true;
// 发起呼叫邀请相关代码/** 向用户发送呼叫邀请 */
const invitees = ['xxxx'];  // 被邀请人ID列表
const config: ZIMCallInviteConfig = {
    mode: 0, 
    extendedData: '',
    timeout: 200, // 邀请超时时间,单位为秒,范围1-600  
    enableNotReceivedCheck: true // 开启暂未送达检测
};  
zim.callInvite(invitees, config)
    .then((res: ZIMCallInvitationSentResult) => {
        const callID = res.callID;
        // 操作成功
        // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })/** 向用户发送呼叫邀请 */
const invitees = ['xxxx'];  // 被邀请人ID列表
const config: ZIMCallInviteConfig = {
    mode: 0, 
    extendedData: '',
    timeout: 200, // 邀请超时时间,单位为秒,范围1-600  
    enableNotReceivedCheck: true // 开启暂未送达检测
};  
zim.callInvite(invitees, config)
    .then((res: ZIMCallInvitationSentResult) => {
        const callID = res.callID;
        // 操作成功
        // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    })
    .catch((err: ZIMError) => {
        // 操作失败
    })主叫发起呼叫邀请后,如果被叫在 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 处理。
// 查询用户自己的呼叫邀请列表 
ZIMCallInvitationQueryConfig queryCallListConfig = new ZIMCallInvitationQueryConfig();
queryCallListConfig.count = 20;
queryCallListConfig.nextFlag = 0;
ZIM.getInstance(). queryCallInvitationList(queryCallListConfig, new ZIMCallInvitationListQueriedCallback() {
    @Override
    public void onCallListQueried(ArrayList<ZIMCallInfo> callList, long nextFlag, ZIMError errorInfo) {
        if(errorInfo.code != ZIMErrorCode.SUCCESS){
            // 根据官网错误码表处理错误
            return;
        }
        if(nextFlag != 0){
            // 如果 callback 返回的 nextFlag 不为 0,代表没有完成查询所有的呼叫邀请信息。下次查询时可以传入 callback 返回的 nextFlag 继续查询剩余呼叫邀请信息
            queryCallListConfig.nextFlag = nextFlag;
        }
    }
});// 查询用户自己的呼叫邀请列表 
ZIMCallInvitationQueryConfig queryCallListConfig = new ZIMCallInvitationQueryConfig();
queryCallListConfig.count = 20;
queryCallListConfig.nextFlag = 0;
ZIM.getInstance(). queryCallInvitationList(queryCallListConfig, new ZIMCallInvitationListQueriedCallback() {
    @Override
    public void onCallListQueried(ArrayList<ZIMCallInfo> callList, long nextFlag, ZIMError errorInfo) {
        if(errorInfo.code != ZIMErrorCode.SUCCESS){
            // 根据官网错误码表处理错误
            return;
        }
        if(nextFlag != 0){
            // 如果 callback 返回的 nextFlag 不为 0,代表没有完成查询所有的呼叫邀请信息。下次查询时可以传入 callback 返回的 nextFlag 继续查询剩余呼叫邀请信息
            queryCallListConfig.nextFlag = nextFlag;
        }
    }
});// 查询用户自己的呼叫邀请列表 
ZIMCallInvitationQueryConfig queryCallListConfig = ZIMCallInvitationQueryConfig();
queryCallListConfig.count = 20;
queryCallListConfig.nextFlag = 0;
ZIM.getInstance()!.queryCallInvitationList(queryCallListConfig).then((ZIMCallInvitationListQueriedResult result) {
    if(result.nextFlag != 0){
      // 如果 callback 返回的 nextFlag 不为 0,代表没有完成查询所有的呼叫邀请信息。下次查询时可以传入 callback 返回的 nextFlag 继续查询剩余呼叫邀请信息
      queryCallListConfig.nextFlag = result.nextFlag;
    }
}).catchError((onError){
    // 根据官网错误码表处理错误
});// 查询用户自己的呼叫邀请列表 
ZIMCallInvitationQueryConfig queryCallListConfig = ZIMCallInvitationQueryConfig();
queryCallListConfig.count = 20;
queryCallListConfig.nextFlag = 0;
ZIM.getInstance()!.queryCallInvitationList(queryCallListConfig).then((ZIMCallInvitationListQueriedResult result) {
    if(result.nextFlag != 0){
      // 如果 callback 返回的 nextFlag 不为 0,代表没有完成查询所有的呼叫邀请信息。下次查询时可以传入 callback 返回的 nextFlag 继续查询剩余呼叫邀请信息
      queryCallListConfig.nextFlag = result.nextFlag;
    }
}).catchError((onError){
    // 根据官网错误码表处理错误
});// 查询用户自己的呼叫邀请列表 
ZIMCallInvitationQueryConfig *config = [[ZIMCallInvitationQueryConfig alloc] init];
// 单次查询 20 条呼叫邀请数据
// count 超过 100 按照 100 处理
config.count = 20; 
// 首次查询 nextFlag 填 0,代表从最新的呼叫邀请(创建时间最晚)开始
config.nextFlag = 0;
[[ZIM getInstance] queryCallInvitationListWithConfig:config callback:^(NSArray<ZIMCallInfo *> * _Nonnull callList, long long nextFlag, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code != ZIMErrorCodeSuccess){
     // 根据官网错误码表处理错误   
        return;
    }
    if(nextFlag != 0){
        // 如果 callback 返回的 nextFlag 不为 0,代表没有完成查询所有的呼叫邀请信息。下次查询时可以传入 callback 返回的 nextFlag 继续查询剩余呼叫邀请信息
        config.nextFlag = nextFlag;
    }
}];// 查询用户自己的呼叫邀请列表 
ZIMCallInvitationQueryConfig *config = [[ZIMCallInvitationQueryConfig alloc] init];
// 单次查询 20 条呼叫邀请数据
// count 超过 100 按照 100 处理
config.count = 20; 
// 首次查询 nextFlag 填 0,代表从最新的呼叫邀请(创建时间最晚)开始
config.nextFlag = 0;
[[ZIM getInstance] queryCallInvitationListWithConfig:config callback:^(NSArray<ZIMCallInfo *> * _Nonnull callList, long long nextFlag, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code != ZIMErrorCodeSuccess){
     // 根据官网错误码表处理错误   
        return;
    }
    if(nextFlag != 0){
        // 如果 callback 返回的 nextFlag 不为 0,代表没有完成查询所有的呼叫邀请信息。下次查询时可以传入 callback 返回的 nextFlag 继续查询剩余呼叫邀请信息
        config.nextFlag = nextFlag;
    }
}];// 查询用户自己的呼叫邀请列表 
ZIMCallInvitationQueryConfig config = ZIMCallInvitationQueryConfig();
// 单次查询 20 条呼叫邀请数据
// 超过 100 条按 100 条处理。
config.count = 20;
// 首次查询 nextFlag 填 0,代表从最新的呼叫邀请(创建时间最晚)开始
config.nextFlag = 0;
    
ZIM::getInstance()->queryCallInvitationList(config, [](const std::vector<ZIMCallInfo> &callList, long long nextFlag, const ZIMError &errorInfo){
    if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
        if(nextFlag != 0){
            // 如果 callback 返回的 nextFlag 不为 0,代表没有完成查询所有的呼叫邀请信息。下次查询时可以传入 callback 返回的 nextFlag 继续查询剩余呼叫邀请信息
        }
    }else{
        // 根据官网错误码表处理错误
    }
});// 查询用户自己的呼叫邀请列表 
ZIMCallInvitationQueryConfig config = ZIMCallInvitationQueryConfig();
// 单次查询 20 条呼叫邀请数据
// 超过 100 条按 100 条处理。
config.count = 20;
// 首次查询 nextFlag 填 0,代表从最新的呼叫邀请(创建时间最晚)开始
config.nextFlag = 0;
    
ZIM::getInstance()->queryCallInvitationList(config, [](const std::vector<ZIMCallInfo> &callList, long long nextFlag, const ZIMError &errorInfo){
    if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS){
        if(nextFlag != 0){
            // 如果 callback 返回的 nextFlag 不为 0,代表没有完成查询所有的呼叫邀请信息。下次查询时可以传入 callback 返回的 nextFlag 继续查询剩余呼叫邀请信息
        }
    }else{
        // 根据官网错误码表处理错误
    }
});/** 
  * 查询呼叫邀请列表
  * 1. 查询用户自己的呼叫邀请列表, 单次查询 20 条呼叫邀请数据  
  * 2. 首次查询 nextFlag 填 0,代表从最新的呼叫邀请(创建时间最晚)开始
  */
const config: ZIMCallInvitationQueryConfig = { count: 20, nextFlag: 0 };
zim.queryCallInvitationList(config)
    .then((res: ZIMCallInvitationListQueriedResult) => {
    // next page
    config.nextFlag = res.nextFlag;
    zim.queryCallInvitationList(config);
});/** 
  * 查询呼叫邀请列表
  * 1. 查询用户自己的呼叫邀请列表, 单次查询 20 条呼叫邀请数据  
  * 2. 首次查询 nextFlag 填 0,代表从最新的呼叫邀请(创建时间最晚)开始
  */
const config: ZIMCallInvitationQueryConfig = { count: 20, nextFlag: 0 };
zim.queryCallInvitationList(config)
    .then((res: ZIMCallInvitationListQueriedResult) => {
    // next page
    config.nextFlag = res.nextFlag;
    zim.queryCallInvitationList(config);
});


