点对点音视频通话
点对点音视频通话功能包含点对点的音频通话和点对点的音视频通话,提供呼叫、接听、挂断、话单通知等功能。通过阅读该章节,您可以快速了解点对点实时音视频通话的流程,帮助您迅速搭建一个最简单的点对点实时音视频通话功能。
呼叫/接听流程
主叫发起通话请求
API介绍
发起一个音视频网络通话。
API原型
C++
static bool Start(NIMVideoChatMode mode, const std::string& apns_text, const std::string& custom_info, const std::string& json_info)
File:nim_cpp_vchat.h
Namespace:NIM
Class:VChat
C#
static bool Start(NIMVideoChatMode mode, string apns_text,NIMVChatInfo info,string customInfo = null)
Namespace:NIM
Class:VChatAPI
C
bool nim_vchat_start(enum NIMVideoChatMode mode, const char *apns_text, const char *custom_info, const char *json_extension, const void *user_data)
File:nim_vchat.h
参数说明
- C++
参数 | 类型 | 说明 |
---|---|---|
mode | enum | 音视频通话类型,音频或音视频 |
apns_text | string | 推送文本,推送给手机显示 |
custom_info | string | 自定义信息,带给接收方 |
json_info | string | Json string 扩展,音视频通话的扩展参数设置 |
- C#
参数 | 类型 | 说明 |
---|---|---|
mode | enum | 音视频通话类型,音频或音视频 |
apns_text | string | 推送文本,推送给手机显示 |
info | Json | json扩展封装类,见NIMVChatInfo |
customInfo | string | 自定义信息,带给接收方 |
- C
参数 | 类型 | 说明 |
---|---|---|
mode | enum | 音视频通话类型,音频或音视频 |
apns_text | string | 推送文本,推送给手机显示 |
custom_info | string | 自定义信息,带给接收方 |
json_extension | string | Json string 扩展,音视频通话的扩展参数设置 |
user_data | void* | 无效扩展 |
返回值说明
返回一个bool类型值。若调用成功返回true,否则返回false。一般失败是由于有正在进行的通话导致。
示例
C++
void foo() { nim::NIMVideoChatMode mode = nim::kNIMVideoChatModeAudio; Json::FastWriter fs; Json::Value value; value[nim::kNIMVChatSessionId] = "session_id"; value[nim::kNIMVChatUids].append("uid"); value[nim::kNIMVChatSound] = "video_chat_tip_receiver.aac"; value[nim::kNIMVChatNeedBadge] = 0; value[nim::kNIMVChatNeedFromNick] = 0; std::string json_value = fs.write(value); nim::VChat::Start(mode, nbase::UTF16ToUTF8(mode == nim::kNIMVideoChatModeAudio ? L"语音通话邀请test" : L"视频通话邀请test"), "test custom info", json_value.c_str()); }
C#
void foo() { NIMVChatInfo info = new NIMVChatInfo(); info.Uids = new System.Collections.Generic.List<string>(); info.Uids.Add("user_id"); VChatAPI.Start(NIMVideoChatMode.kNIMVideoChatModeVideo, "", info);//邀请user_id进行语音通话 }
C
typedef bool(*nim_vchat_start)(NIMVideoChatMode mode, const char* apns_text, const char* custom_info, const char* json_extension, const void *user_data); void foo() { nim::NIMVideoChatMode mode = nim::kNIMVideoChatModeAudio; Json::FastWriter fs; Json::Value value; value[nim::kNIMVChatSessionId] = "session_id"; value[nim::kNIMVChatUids].append("uid"); value[nim::kNIMVChatSound] = "video_chat_tip_receiver.aac"; value[nim::kNIMVChatNeedBadge] = 0; value[nim::kNIMVChatNeedFromNick] = 0; std::string json_value = fs.write(value); nim_vchat_start func = (nim_vchat_start) GetProcAddress(hInst, "nim_vchat_start"); func(mode, nbase::UTF16ToUTF8(mode == nim::kNIMVideoChatModeAudio ? L"语音通话邀请test" : L"视频通话邀请test"), "test custom info", json_value.c_str(), nullptr); }
特殊说明
在通话发起时,应该设置一个定时器,用于在通话建立前等待超时时能主动结束通话。
- C#
扩展参数全在NIMVChatInfo info中,发起结果回调见NIMVChatSessionStatus.onSessionStartRes
- C++/C
扩展参数见音视频相关扩展发起参数,发起结果回调见nim_vchat_cb_func,返回类型NIMVideoChatSessionType::kNIMVideoChatSessionTypeStartRes
被叫收到通话请求回调
API介绍
收到一个点对点音视频通话的邀请。由注册通话事件后,在回调中区分。
API原型
C#
NIMVChatSessionStatus.onSessionInviteNotify
public delegate void onSessionInviteNotifyHandler(long channel_id, string uid, int mode, long time, string customInfo)
Namespace:NIM
Class:VChatAPI
C++/C
typedef void (*nim_vchat_cb_func)(enum NIMVideoChatSessionType type, int64 channel_id, int code, const char *json_extension, const void *user_data)
NIMVideoChatSessionType::kNIMVideoChatSessionTypeInviteNotify
File:nim_vchat_def.h
参数说明
- C#
参数 | 类型 | 说明 |
---|---|---|
channel_id | long | 频道id |
uid | string | 邀请者uid |
mode | int | 通话类型 |
time | long | 时间戳(毫秒级) |
customInfo | string | 自定义信息 |
- C++/C
参数 | 类型 | 说明 |
---|---|---|
type | enum | 回调类型kNIMVideoChatSessionTypeInviteNotify |
channel_id | int64 | 频道id |
code | int | 无效错误码 |
json_extension | string | Json string 扩展,返回kNIMVChatUid发起者,kNIMVChatType对应NIMVideoChatMode, kNIMVChatTime, kNIMVChatCustomInfo |
user_data | void* | 注册回调时的APP自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
示例
C#
private static void OnSessionInviteNotify(long channel_id, string uid, int mode, long time,string custom_info) { Action a = () => { string test = uid.ToString(); if (mode == (int)NIM.NIMVideoChatMode.kNIMVideoChatModeAudio) { test += "向你发起实时语音"; } else { test += "向你发起视频聊天"; } DialogResult ret = MessageBox.Show(test, "音视频邀请", MessageBoxButtons.YesNo); NIM.NIMVChatInfo info = new NIM.NIMVChatInfo(); NIM.VChatAPI.CalleeAck(channel_id, ret == DialogResult.Yes, info); }; _ownerFriendsListForm.BeginInvoke(a); }
C++/C
void VChatCb(nim::NIMVideoChatSessionType type, __int64 channel_id, int code, const char *json, const void*) { switch (type) { case nim::kNIMVideoChatSessionTypeInviteNotify: { Json::Value valus; Json::Reader reader; if (reader.parse(json, valus)) { std::string uid = valus[nim::kNIMVChatUid].asString(); int mode = valus[nim::kNIMVChatType].asInt(); //尝试打开新的通话 if (!ShowVideoChatForm(uid, mode == nim::kNIMRtsVideoChatModeVideo, channel_id)) { //已有通话存在,通知对方正忙并直接拒绝 VChat::Control(channel_id, nim::kNIMTagControlBusyLine); VChat::CalleeAck(channel_id, false, ""); } else { //没有通话存在,通知对方已接收到 VChat::Control(channel_id, nim::kNIMTagControlReceiveStartNotifyFeedback); } } } break; //··· } }
被叫响应通话请求
API介绍
通知邀请方自己的处理结果。如果已有通话存在,需要结束已有通话才能接听新的通话。
API原型
C++
static bool CalleeAck(uint64_t channel_id, bool accept, const std::string& json_extension)
File:nim_cpp_vchat.h
Namespace:NIM
Class:VChat
C#
public static bool CalleeAck(long channel_id, bool accept, NIMVChatInfo info)
Namespace:NIM
Class:VChatAPI
C
bool nim_vchat_callee_ack(int64 channel_id, bool accept, const char *json_extension, const void *user_data)
File:nim_vchat.h
参数说明
- C++
参数 | 类型 | 说明 |
---|---|---|
channel_id | uint64_t | 频道id |
accept | bool | 是否接听 |
json_extension | string | Json string 扩展,音视频通话的扩展参数设置 |
- C#
参数 | 类型 | 说明 |
---|---|---|
channel_id | long | 频道id |
accept | bool | 是否接听 |
info | Json | json扩展封装类,见NIMVChatInfo |
- C
参数 | 类型 | 说明 |
---|---|---|
channel_id | uint64_t | 频道id |
accept | bool | 是否接听 |
json_extension | string | Json string 扩展,音视频通话的扩展参数设置 |
user_data | void* | 无效扩展 |
返回值说明
返回一个bool类型值。若调用成功返回true,否则返回false。
示例
C++
void foo(uint64_t channel_id, bool accept, const std::string& session_id) { std::string json_value; if (accept) { Json::FastWriter fs; Json::Value value; value[nim::kNIMVChatVideoQuality] = 0; value[nim::kNIMVChatRecord] = 1; value[nim::kNIMVChatVideoRecord] = 1; value[nim::kNIMVChatSessionId] = session_id; json_value = fs.write(value); } nim::VChat::CalleeAck(channel_id, accept, json_value); }
C#
void foo() { NIM.NIMVChatInfo info = new NIM.NIMVChatInfo(); NIM.VChatAPI.CalleeAck(channel_id, true, info); }
C
typedef bool(*nim_vchat_callee_ack)(__int64 channel_id, bool accept, const char* json_extension, const void *user_data); void foo(uint64_t channel_id, bool accept, const std::string& session_id) { std::string json_value; if (accept) { Json::FastWriter fs; Json::Value value; value[nim::kNIMVChatVideoQuality] = 0; value[nim::kNIMVChatRecord] = 1; value[nim::kNIMVChatVideoRecord] = 1; value[nim::kNIMVChatSessionId] = session_id; json_value = fs.write(value); } nim_vchat_callee_ack func = (nim_vchat_callee_ack) GetProcAddress(hInst, "nim_vchat_callee_ack"); func(channel_id, accept, json_value.c_str(), nullptr); }
特殊说明
在通话接听时,应该设置一个定时器,用于在通话建立前等待超时时能主动结束通话。
C#
扩展参数全在NIMVChatInfo info中,发起结果回调见NIMVChatSessionStatus.onSessionCalleeAckRes
C++/C
扩展参数见音视频相关扩展发起参数,接听结果回调见nim_vchat_cb_func,返回类型NIMVideoChatSessionType::kNIMVideoChatSessionTypeCalleeAckRes
主叫收到被叫响应回调
API介绍
收到被叫方响应的回调信息通知。由注册通话事件后,在回调中区分。
API原型
C#
NIMVChatSessionStatus.onSessionCalleeAckNotify
public delegate void onSessionCalleeAckNotifyHandler(long channel_id, string uid, int mode, bool accept)
Namespace:NIM
Class:VChatAPI
C++/C
typedef void (*nim_vchat_cb_func)(enum NIMVideoChatSessionType type, int64 channel_id, int code, const char *json_extension, const void *user_data)
NIMVideoChatSessionType::kNIMVideoChatSessionTypeCalleeAckNotify
File:nim_vchat_def.h
参数说明
- C#
参数 | 类型 | 说明 |
---|---|---|
channel_id | long | 频道id |
uid | string | 被邀请者uid |
mode | int | 通话类型 |
accept | bool | 是否接听 |
- C++/C
参数 | 类型 | 说明 |
---|---|---|
type | enum | 回调类型kNIMVideoChatSessionTypeCalleeAckNotify |
channel_id | int64 | 频道id |
code | int | 无效错误码 |
json_extension | string | Json string 扩展,返回kNIMVChatUid被邀请者,kNIMVChatType对应NIMVideoChatMode, kNIMVChatAccept |
user_data | void* | 注册回调时的APP自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
示例
C#
private static void OnSessionCalleeAckNotify(long channel_id, string uid, int mode, bool accept,string customInfo) { if (accept) { DemoTrace.WriteLine("对方接听"); } else { Action a = () => { MessageBox.Show("对方拒绝接听"); }; _ownerFriendsListForm.Invoke(a); } }
C++/C
void VChatCb(nim::NIMVideoChatSessionType type, __int64 channel_id, int code, const char *json, const void*) { switch (type) { case nim::kNIMVideoChatSessionTypeCalleeAckNotify: { Json::Value valus; Json::Reader reader; if (reader.parse(json, valus)) { //std::string uid = valus[nim::kNIMVChatUid].asString(); //int mode = valus[nim::kNIMVChatType].asInt(); bool accept = valus[nim::kNIMVChatAccept].asInt() > 0; VideoForm *window = (VideoForm*)(WindowsManager::GetInstance()->GetWindow(VideoForm::kClassName, VideoForm::kClassName)); if (window && window->IsStart()) { if (!accept) { window->OnRejected(channel_id); } } } } break; //··· } }
呼入的通话已经被该帐号其他端处理回调
API介绍
收到本人在别的端响应的回调通知。由注册通话事件后,在回调中区分。
API原型
C#
NIMVChatSessionStatus.onSessionSyncAckNotify
public delegate void onSessionSyncAckNotifyHandler(long channel_id, int code, string uid, int mode, bool accept, long time, int client)
Namespace:NIM
Class:VChatAPI
C++/C
typedef void (*nim_vchat_cb_func)(enum NIMVideoChatSessionType type, int64 channel_id, int code, const char *json_extension, const void *user_data)
NIMVideoChatSessionType::kNIMVideoChatSessionTypeSyncAckNotify
File:nim_vchat_def.h
参数说明
- C#
参数 | 类型 | 说明 |
---|---|---|
channel_id | long | 频道id |
uid | string | 无效 |
mode | int | 通话类型 |
accept | bool | 是否接听 |
time | long | 时间戳(毫秒级) |
client | int | 处理响应的客户端类型 |
- C++/C
参数 | 类型 | 说明 |
---|---|---|
type | enum | 回调类型kNIMVideoChatSessionTypeSyncAckNotify |
channel_id | int64 | 频道id |
code | int | 无效错误码 |
json_extension | string | Json string 扩展,返回 kNIMVChatTime,kNIMVChatType对应NIMVideoChatMode,kNIMVChatAccept,kNIMVChatClient |
user_data | void* | 注册回调时的APP自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
示例
- C#
private static void OnSessionSyncAckNotify(channel_id,code,uid, mode, accept, time, client)
{
EndDevices();
if (code == 200)
{
Action action = () =>
{
MessageBox.Show("已在其他端接听");
MainForm.VideoChatForm vform = MainForm.VideoChatForm.GetInstance();
if (vform != null)
{
vform.Close();
}
};
_ownerFriendsListForm.Invoke(action);
}
}
C++/C
void VChatCb(nim::NIMVideoChatSessionType type, __int64 channel_id, int code, const char *json, const void*) { switch (type) { case nim::kNIMVideoChatSessionTypeInviteNotify: { Json::Value valus; Json::Reader reader; if (reader.parse(json, valus)) { bool accept = valus[nim::kNIMVChatAccept].asInt() > 0; int client = valus[nim::kNIMVChatClient].asInt(); VideoForm *window = (VideoForm*)(WindowsManager::GetInstance()->GetWindow(VideoForm::kClassName, VideoForm::kClassName)); if (window) { window->OnVideochatSyncNotify(accept, channel_id); } } } break; //··· } }
通话建立成功
API介绍
通话在对方接听后,双方底层都开始建立连接,以对方加入通话为通话建立成果的标记。
API原型
C#
连接状态:
NIMVChatSessionStatus.onSessionConnectNotify
public delegate void onSessionConnectNotifyHandler(long channel_id, int code, string record_file, string video_record_file)
对端进出:
NIMVChatSessionStatus.onSessionPeopleStatus
public delegate void onSessionPeopleStatusHandler(long channel_id, string uid, int status)
Namespace:NIM
Class:VChatAPI
C++/C
typedef void (*nim_vchat_cb_func)(enum NIMVideoChatSessionType type, int64 channel_id, int code, const char *json_extension, const void *user_data)
连接状态:
NIMVideoChatSessionType::kNIMVideoChatSessionTypeConnect
对端进出:
NIMVideoChatSessionType::kNIMVideoChatSessionTypePeopleStatus
File:nim_vchat_def.h
参数说明
- C#
参数 | 类型 | 说明 |
---|---|---|
channel_id | long | 频道id |
code | int | 状态码 |
record_file | string | 服务器录制的音频文件名 |
video_record_file | string | 服务器录制的视频文件名 |
uid | string | 对方id |
status | int | 成员状态,离开、加入等 |
- C++/C
连接状态:
参数 | 类型 | 说明 |
---|---|---|
type | enum | 回调类型kNIMVideoChatSessionTypeConnect |
channel_id | int64 | 频道id |
code | int | 错误码NIMVChatConnectErrorCode,200代表连接成功 |
json_extension | string | Json string 扩展,如果成功返回 kNIMVChatVideoRecordFile和kNIMVChatRecordFile |
user_data | void* | 注册回调时的APP自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
对端进出:
参数 | 类型 | 说明 |
---|---|---|
type | enum | 回调类型kNIMVideoChatSessionTypePeopleStatus |
channel_id | int64 | 频道id |
code | int | 状态码,对应NIMVideoChatSessionStatus |
json_extension | string | Json string 扩展,返回kNIMVChatUid,如果是离开带kNIMVChatStatus对应NIMVideoChatUserLeftType |
user_data | void* | 注册回调时的APP自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
示例
C#
private static void OnSessionConnectNotify(long channel_id, int code, string record_file, string video_record_file) { //连接成功 if (code == 200) { Action a = () => { if (NIMDemo.Helper.VChatHelper.CurrentVChatType == NIMDemo.Helper.VChatType.kP2P) { MainForm.VideoChatForm vform = MainForm.VideoChatForm.GetInstance(); vform.Show(); } }; _ownerFriendsListForm.Invoke(a); StartDevices(); } else { NIM.VChatAPI.End(); } } private static void OnSessionPeopleStatus(long channel_id, string uid, int status) { DemoTrace.WriteLine("SessionPeopleStatus channel_id:" + channel_id.ToString() + " status:" + status.ToString() + " uid:" + uid); if (status == NIMVideoChatSessionStatus.kNIMVideoChatSessionStatusJoined) { MessageBox.Show("通话建立成功"); } }
C++/C
void VChatCb(nim::NIMVideoChatSessionType type, __int64 channel_id, int code, const char *json, const void*) { switch (type) { case nim::kNIMVideoChatSessionTypeConnect:{ if (code == 200) { //连接成功 } else { //连接失败 } }break; case nim::kNIMVideoChatSessionTypePeopleStatus:{ if (code == nim::kNIMVideoChatSessionStatusJoined) { //通话建立成功 } else if (code == nim::kNIMVideoChatSessionStatusLeaved) { Json::Value valus; Json::Reader reader; if (reader.parse(json, valus)) { std::string uid = valus[nim::kNIMVChatUid].asString(); int32_t leave_type = valus[nim::kNIMVChatStatus].asInt(); if (leave_type == 0) { //成员 uid 离开 } else { //成员 uid 超时离开 } } } }break; //··· } }
特殊说明
在主叫发起通话和被叫收到邀请后,都应该创建一个定时器,当通话建立超时时,应该按创建失败的流程结束通话。
挂断流程
结束通话
API介绍
需要在通话结束时调用,用于底层挂断和清理数据,如果是自己主动结束会通知对方。
API原型
C++
static void End(const std::string& json_extension);
File:nim_cpp_vchat.h
Namespace:NIM
Class:VChat
C#
public static void End(string jsonExtension="")
Namespace:NIM
Class:VChatAPI
C
void nim_vchat_end(const char *json_extension)
File:nim_vchat.h
参数说明
需要带上session_id。用于关闭对应的通话。
- C++
参数 | 类型 | 说明 |
---|---|---|
json_extension | string | Json string 扩展,kNIMVChatSessionId |
- C#
参数 | 类型 | 说明 |
---|---|---|
jsonExtension | string | Json string 扩展,kNIMVChatSessionId |
- C
参数 | 类型 | 说明 |
---|---|---|
json_extension | string | Json string 扩展,kNIMVChatSessionId |
返回值说明
无返回值。
示例
C++
void foo() { Json::FastWriter fs; Json::Value value; value[nim::kNIMVChatSessionId] = session_id; std::string json_value = fs.write(value); nim::VChat::End(json_value); }
C#
void foo() { string json = "{\"session_id\":\"session_id_temp\"}"; NIM.VChatAPI.End(json); }
C
typedef void(*nim_vchat_end)(const char* json_extension); void foo() { nim_vchat_end func = (nim_vchat_end) GetProcAddress(hInst, "nim_vchat_end"); Json::FastWriter fs; Json::Value value; value[nim::kNIMVChatSessionId] = session_id; std::string json_value = fs.write(value); func(json_value.c_str()); }
特殊说明
主动结束会返回hangup调用结果的回调通知,对于已经建立连接的通话,结束后返回connect的回调通知,code=1001(kNIMVChatConnectLogout)
收到对方结束通话回调
API介绍
对端主动结束通话,另一端会收到挂断通知。
API原型
C#
NIMVChatSessionStatus.onSessionHangupNotify
public delegate void onSessionHandler(long channel_id, int code)
Namespace:NIM
Class:VChatAPI
C++/C
typedef void (*nim_vchat_cb_func)(enum NIMVideoChatSessionType type, int64 channel_id, int code, const char *json_extension, const void *user_data)
NIMVideoChatSessionType::kNIMVideoChatSessionTypeHangupNotify
File:nim_vchat_def.h
参数说明
- C#
参数 | 类型 | 说明 |
---|---|---|
channel_id | long | 频道id |
code | int | 错误码 |
- C++/C
参数 | 类型 | 说明 |
---|---|---|
type | enum | 回调类型kNIMVideoChatSessionTypeHangupNotify |
channel_id | int64 | 频道id |
code | int | 错误码 |
json_extension | string | 无效 Json string 扩展 |
user_data | void* | 注册回调时的APP自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
示例
C#
private static void OnSessionHangupNotify(long channel_id, int code) { EndDevices(); if (code == 200) { Action action = () => { MessageBox.Show("已挂断"); MainForm.VideoChatForm vform = MainForm.VideoChatForm.GetInstance(); if (vform != null) { vform.Close(); } }; _ownerFriendsListForm.Invoke(action); } }
C++/C
void VChatCb(nim::NIMVideoChatSessionType type, __int64 channel_id, int code, const char *json, const void*) { switch (type) { case nim::kNIMVideoChatSessionTypeHangupNotify:{ VideoForm *window = (VideoForm*)(WindowsManager::GetInstance()->GetWindow(VideoForm::kClassName, VideoForm::kClassName)); if (window) { window->OnHangup(channel_id); } }break; //··· } }
通话断开
API介绍
在通话建立后,会有connect的通知,告知200的成功状态。之后connect返回非200都代表通话断开。
API原型
C#
NIMVChatSessionStatus.onSessionConnectNotify
public delegate void onSessionConnectNotifyHandler(long channel_id, int code, string record_file, string video_record_file)
Namespace:NIM
Class:VChatAPI
C++/C
typedef void (*nim_vchat_cb_func)(enum NIMVideoChatSessionType type, int64 channel_id, int code, const char *json_extension, const void *user_data)
NIMVideoChatSessionType::kNIMVideoChatSessionTypeConnect
File:nim_vchat_def.h
参数说明
- C#
参数 | 类型 | 说明 |
---|---|---|
channel_id | long | 频道id |
code | int | 状态码 |
record_file | string | 服务器录制的音频文件名 |
video_record_file | string | 服务器录制的视频文件名 |
- C++/C
参数 | 类型 | 说明 |
---|---|---|
type | enum | 回调类型kNIMVideoChatSessionTypeConnect |
channel_id | int64 | 频道id |
code | int | 错误码NIMVChatConnectErrorCode,200代表连接成功 |
json_extension | string | Json string 扩展,如果成功返回 kNIMVChatVideoRecordFile和kNIMVChatRecordFile |
user_data | void* | 注册回调时的APP自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
示例
C#
private static void OnSessionConnectNotify(long channel_id, int code, string record_file, string video_record_file) { if (code != 200) { //通话断开 NIM.VChatAPI.End(); } }
C++/C
void VChatCb(nim::NIMVideoChatSessionType type, __int64 channel_id, int code, const char *json, const void*) { switch (type) { case nim::kNIMVideoChatSessionTypeConnect:{ if (code != 200) { //通话断开 } }break; //··· } }
特殊说明
大部分因为网络原因导致的通话断开,都会在连接超时后返回connect通知,并且这个超时和IM的账号登陆长链接无关联。
话单通知
API介绍
在一通通话结束后,会返回一个通话话单,以IM自定义系统消息的形式发出。
API原型
C++
在线消息广播通知:
static void RegReceiveCb (const ReceiveMsgCallback &cb, const std::string &json_extension="")
离线、同步消息广播通知:
static void RegReceiveMessagesCb (const ReceiveMsgsCallback &cb, const std::string &json_extension="")
File:nim_cpp_talk.h
Namespace:NIM
Class:Talk
C#
在线消息广播通知:
static EventHandler< NIMReceiveMessageEventArgs> OnReceiveMessageHandler [get, set]
离线、同步消息广播通知:
static void RegReceiveBatchMessagesCb (ReceiveBatchMesaagesDelegate cb)
Namespace:NIM
Class:TalkAPI
C
在线消息广播通知:
NIM_SDK_DLL_API void nim_talk_reg_receive_cb (const char *json_extension, nim_talk_receive_cb_func cb, const void *user_data)
离线、同步消息广播通知:
NIM_SDK_DLL_API void nim_talk_reg_receive_msgs_cb (const char *json_extension, nim_talk_receive_cb_func cb, const void *user_data)
File:nim_talk.h
参数说明
参数 | 类型 | 说明 |
---|---|---|
json_extension | string | json 扩展 |
cb | function | 音视频通话回调接口 |
user_data | void* | APP的自定义用户数据,SDK只负责传回给回调函数cb,不做任何处理 |
示例
C++
void OnReceiveMsgCallback(const nim::IMMessage& message) { //系统类型通知 if (message.type_ == nim::kNIMMessageTypeNotification) { message.msg_attach_; //··· } } void foo() { nim::Talk::RegReceiveCb(&OnReceiveMsgCallback); }
C#
void OnReceiveMessage(object sender, NIM.NIMReceiveMessageEventArgs args) { //系统类型通知 if (args.Message != null && args.Message.MessageContent.MessageType == NIMMessageType.kNIMMessageTypeNotification) { args.Message.Attach; //··· } } private void foo() { NIM.TalkAPI.OnReceiveMessageHandler += OnReceiveMessage; }
C
void CallbackReceiveMsg(const char* msg, const char *json_exten, const void *user_data) { Json::Value value; Json::Reader reader; if (reader.parse(msg, value)) { int type = (NIMMessageType)value[kNIMMsgKeyType].asUInt(); std::string attach = value[kNIMMsgKeyAttach].asString();; if (type == nim::kNIMMessageTypeNotification) { Json::Value value2; Json::Reader reader2; if (reader2.parse(attach, value2)) { nim::NIMNotificationId id = (nim::NIMNotificationId)value2[nim::kNIMNotificationKeyId].asInt(); //话单信息call_json Json::Value call_json = value2[nim::kNIMNotificationKeyData]; //通话类型 int type = call_json[nim::kNIMNotificationIdNetCallTypeKey].asUInt(); //通话id int64_t cid = call_json[kNIMNotificationIdNetCallChannelKey].asInt64(); //发起人 std::string call_uid = call_json[kNIMNotificationIdNetCallFromKey].asString(); //通话发起时间 int64_t call_time = call_json[kNIMNotificationIdNetCallTimeKey].asInt64(); if (id == nim::kNIMNotificationIdNetcallMiss) { /**< 未接电话,{"calltype":1,"channel":6146078138783760761,"from":"id1","ids":["id1","id2"],"time":1430995380471}*/ } else if (id == nim::kNIMNotificationIdNetcallBill) { /**< 话单,{"calltype":2,"channel":6146077129466446197,"duration":8,"ids":["id1","id2"],"time":1430995117398}*/ //通话时长 __int64 duration = call_json[nim::kNIMNotificationIdNetCallDurationKey].asInt64(); } else if (id == nim::kNIMNotificationIdLocalNetcallReject) { /**< 拒绝电话,{"calltype":1,"channel":6146078138783760761,"from":"id1","ids":["id1","id2"],"time":1430995380471}*/ } else if (id == nim::kNIMNotificationIdLocalNetcallNoResponse) { /**< 无应答,未接通电话,{"calltype":1,"channel":6146078138783760761,"from":"id1","ids":["id1","id2"],"time":1430995380471}*/ } } } } } typedef void(*nim_talk_reg_receive_cb)(const char *json_extension, nim_talk_receive_cb_func cb, const void* user_data); void foo() { nim_talk_reg_receive_cb func = (nim_talk_reg_receive_cb) GetProcAddress(hInst, "nim_talk_reg_receive_cb"); func(nullptr, &CallbackReceiveMsg, nullptr); }
特殊说明
通过IM消息中的系统通知,得到对应的attach,话单详情可以参考C代码示例中的attach解析。