设为首页收藏本站

AnyChat技术支持论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 41174|回复: 107

AnyChat视频呼叫业务逻辑详解

[复制链接]

7

主题

332

帖子

1539

积分

金牌会员

Rank: 6Rank: 6

积分
1539
发表于 2013-9-6 15:12:16 | 显示全部楼层 |阅读模式
本帖最后由 佰锐技术-卓剑锐 于 2014-10-11 11:31 编辑

新版本AnyChat已经内置视频呼叫(VideoCall)业务逻辑,简化应用层开发工作量,下面详细讲解视频呼叫业务逻辑:
一、视频呼叫业务逻辑概述
视频呼叫业务逻辑主要实现两个终端(PC、手机、Pad等)之间的通话请求流程控制,包括请求(Request)、回复(Reply)、开始(Start)以及结束(Finish)等过程,可以形象理解为打电话的流程:拨号、等待、通话、挂断。

二、视频呼叫业务逻辑流程图
videocall_logic.jpg

三、视频呼叫业务逻辑API接口
客户端新增回调函数:

  1. // 视频通话消息通知回调函数定义
  2. typedef void (CALLBACK * BRAC_VideoCallEvent_CallBack)(DWORD dwEventType, DWORD dwUserId, DWORD dwErrorCode, DWORD dwFlags, DWORD dwParam, LPCTSTR lpUserStr, LPVOID lpUserValue);
  3. // 设置视频通话消息通知回调函数
  4. BRAC_API DWORD BRAC_SetVideoCallEventCallBack(BRAC_VideoCallEvent_CallBack lpFunction, LPVOID lpUserValue);
复制代码
客户端新增API接口:

  1. // 视频呼叫事件控制(请求、回复、挂断等)
  2. BRAC_API DWORD BRAC_VideoCallControl(DWORD dwEventType, DWORD dwUserId, DWORD dwErrorCode, DWORD dwFlags, DWORD dwParam, LPCTSTR lpUserStr);
复制代码
服务器新增回调函数

  1. // 视频通话消息通知回调函数定义
  2. typedef DWORD (CALLBACK * BRAS_OnVideoCallEvent_CallBack)(DWORD dwEventType, DWORD dwSrcUserId, DWORD dwTarUserId, DWORD dwErrorCode, DWORD dwFlags, DWORD dwParam, LPCTSTR lpUserStr, LPVOID lpUserValue);
  3. // 设置视频通话消息通知回调函数
  4. BRAS_API DWORD BRAS_SetOnVideoCallEventCallBack(BRAS_OnVideoCallEvent_CallBack lpFunction, LPVOID lpUserValue=NULL);
复制代码
服务器新增API接口:

  1. // 视频呼叫事件控制(请求、回复、挂断等)
  2. BRAS_API DWORD BRAS_VideoCallControl(DWORD dwEventType, DWORD dwUserId, DWORD dwErrorCode, DWORD dwFlags, DWORD dwParam, LPCTSTR lpUserStr);

复制代码
常量定义

  1. // 视频呼叫事件类型定义(API:BRAC_VideoCallControl 传入参数、VideoCallEvent回调参数)
  2. #define BRAC_VIDEOCALL_EVENT_REQUEST              1        ///< 呼叫请求
  3. #define BRAC_VIDEOCALL_EVENT_REPLY                2        ///< 呼叫请求回复
  4. #define BRAC_VIDEOCALL_EVENT_START                3        ///< 视频呼叫会话开始事件
  5. #define BRAC_VIDEOCALL_EVENT_FINISH               4        ///< 挂断(结束)呼叫会话

  6. // 视频呼叫标志定义(API:BRAC_VideoCallControl 传入参数)
  7. #define BRAC_VIDEOCALL_FLAGS_AUDIO             0x01        ///< 语音通话
  8. #define BRAC_VIDEOCALL_FLAGS_VIDEO             0x02        ///< 视频通话
  9. #define BRAC_VIDEOCALL_FLAGS_FBSRCAUDIO        0x10        ///< 禁止源(呼叫端)音频
  10. #define BRAC_VIDEOCALL_FLAGS_FBSRCVIDEO        0x20        ///< 禁止源(呼叫端)视频
  11. #define BRAC_VIDEOCALL_FLAGS_FBTARAUDIO        0x40        ///< 禁止目标(被呼叫端)音频
  12. #define BRAC_VIDEOCALL_FLAGS_FBTARVIDEO        0x80        ///< 禁止目标(被呼叫端)视频

  13. // 视频呼叫
  14. #define AC_ERROR_VIDEOCALL_CANCEL             100101       ///< 源用户主动放弃会话
  15. #define AC_ERROR_VIDEOCALL_OFFLINE            100102       ///< 目标用户不在线
  16. #define AC_ERROR_VIDEOCALL_BUSY               100103       ///< 目标用户忙
  17. #define AC_ERROR_VIDEOCALL_REJECT             100104       ///< 目标用户拒绝会话
  18. #define AC_ERROR_VIDEOCALL_TIMEOUT            100105       ///< 会话请求超时
  19. #define AC_ERROR_VIDEOCALL_DISCONNECT         100106       ///< 网络断线
复制代码
四、其它
1、客户端API(BRAC_VideoCallControl)和回调函数(BRAC_VideoCallEvent_CallBack)中的dwUserId均为对方的用户ID;2、被呼叫方拒绝通话时,发送回复(Reply)指令,dwErrorCode=100104;
3、被呼叫方同意通话时,发送回复(Reply)指令,dwErrorCode=0,然后服务器会向双方发送通话开始(Start)指令,dwParam=RoomId,房间号由核心服务器自动分配;
4、结束通话时,任何一方(包括业务服务器)均可以发送结束(Finish)指令,然后服务器会向双方发送通话结束(Finish)指令;
5、业务服务器可干预呼叫流程:在BRAS_OnVideoCallEvent_CallBack收到呼叫请求指令后,返回0表示允许呼叫,否则为出错代码,不允许呼叫;在会话过程中可以发送结束(Finish)指令,强制挂断指定用户的通话;
6、API接口中的dwParam(整型)、lpUserStr(字符串)均为用户自定义用途;
7、一个用户同时只能发起一路呼叫请求,也同时只能被一个用户呼叫;
8、视频呼叫业务流程可以脱离业务服务器,由核心服务器独立支撑,可以不需要在服务器端进行二次开发。







回复

使用道具 举报

5

主题

1269

帖子

3677

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3677
发表于 2013-9-10 10:55:44 | 显示全部楼层
本帖最后由 廖斌 于 2013-10-12 14:07 编辑

下面android端为例,展示实现视频呼叫业务逻辑的整个过程(代码仅供参考,根据实际情况调用)
一、设置呼叫回调事件接收
用户收到呼叫请求、请求回复、会话开始、会话结束等事件都是在呼叫回调事件中处理的。
1、首先要在目标activity中实现AnyChatVideoCallEvent接口
2、然后在接收之前设置回调接收anychat.SetVideoCallEvent(this);

二、发送呼叫请求
1、用户A请求呼叫用户B,调用如下代码:
  1. anychat.VideoCallControl(AnyChatDefine.BRAC_VIDEOCALL_EVENT_REQUEST, useridB, 0, 0,0, "usernameA")
复制代码
发送呼叫请求。
其中“AnyChatDefine.BRAC_VIDEOCALL_EVENT_REQUEST”为请求呼叫类型,“useridB”为用户B的userId,“usernameA”是自定义参数(这里可以传送A的userName)。
2、服务器接收到之后会判断B用户是否在线、是否正在呼叫,并返回“呼叫请求回复”给A,A触发OnAnyChatVideoCallEvent。
  1.         public void OnAnyChatVideoCallEvent(int dwEventType, final int dwUserId,
  2.                         int dwErrorCode, final int dwFlags, final int dwParam, final String userStr) {
  3.                 // TODO Auto-generated method stub
  4.                 switch(dwEventType)
  5.                 {
  6.                 case AnyChatDefine.BRAC_VIDEOCALL_EVENT_REPLY:
  7.                         switch(dwErrorCode)
  8.                         {
  9.                         case AnyChatDefine.RETURNCODE_SUCCESS:
  10.                                 showToast("呼叫成功,请等待");
  11.                                  dialogCall=new ProgressDialog(this);
  12.                                 dialogCall.setMessage("呼叫成功,请等待");
  13.                         dialogCall.setButton("取消呼叫", new DialogInterface.OnClickListener() {
  14.                                 
  15.                                 @Override
  16.                                 public void onClick(DialogInterface dialog, int which) {
  17.                                         // TODO Auto-generated method stub
  18.                                         anychat.VideoCallControl(AnyChatDefine.BRAC_VIDEOCALL_EVENT_REPLY, dwUserId, AnyChatDefine.RETURNCODE_SESSION_QUIT, dwFlags, 30, anychat.GetUserName(-1));
  19.                                 }
  20.                         });
  21.                                 dialogCall.show();
  22.                                 
  23.                                 break;
  24.                         case AnyChatDefine.RETURNCODE_SESSION_BUSY:
  25.                                 showToast("目标用户忙");
  26.                                 break;
  27.                         case AnyChatDefine.RETURNCODE_SESSION_DISCONNECT:
  28.                                 showToast("网络断线");
  29.                                 break;
  30.                         case AnyChatDefine.RETURNCODE_SESSION_OFFLINE:
  31.                                 showToast("目标用户不在线");
  32.                                 break;
  33.                         case AnyChatDefine.RETURNCODE_SESSION_QUIT:
  34.                                 showToast("源用户主动放弃会话");
  35.                                 break;
  36.                         case AnyChatDefine.RETURNCODE_SESSION_REFUSE:
  37.                                 showToast("目标用户拒绝会话");
  38.                                 if(dialogCall!=null)
  39.                                         dialogCall.dismiss();
  40.                                 break;
  41.                         case AnyChatDefine.RETURNCODE_SESSION_TIMEOUT:
  42.                                 showToast("会话请求超时");
  43.                                 break;
  44.                                 
  45.                                 
  46.                         }
  47.                         break;
复制代码
3、如B是空闲的,服务器会转发“请求指令”给B,B触发OnAnyChatVideoCallEvent
  1.         switch(dwEventType)
  2.                 {
  3.                 case AnyChatDefine.BRAC_VIDEOCALL_EVENT_REQUEST:
  4.                          dialogRequest = new AlertDialog.Builder(this).setPositiveButton("同意", new DialogInterface.OnClickListener() {
  5.                                        
  6.                                         @Override
  7.                                         public void onClick(DialogInterface dialog, int which) {
  8.                                                 // TODO Auto-generated method stub
  9.                                                 targetUserId=String.valueOf(dwUserId);
  10.                                                 anychat.VideoCallControl(AnyChatDefine.BRAC_VIDEOCALL_EVENT_REPLY, dwUserId, AnyChatDefine.RETURNCODE_SUCCESS, dwFlags, 10, anychat.GetUserName(-1));
  11.                                         }
  12.                                 }).setNegativeButton("拒绝", new DialogInterface.OnClickListener() {
  13.                                        
  14.                                         @Override
  15.                                         public void onClick(DialogInterface dialog, int which) {
  16.                                                 // TODO Auto-generated method stub
  17.                                                 Log.i("ANYCHAT", "REPLY:"+"EVENT:"+AnyChatDefine.BRAC_VIDEOCALL_EVENT_REPLY+"dwUserId:"+dwUserId+"ERRORCODE:"+AnyChatDefine.RETURNCODE_SESSION_REFUSE+"NAME:"+anychat.GetUserName(-1));
  18.                                                 anychat.VideoCallControl(AnyChatDefine.BRAC_VIDEOCALL_EVENT_REPLY, dwUserId, AnyChatDefine.RETURNCODE_SESSION_REFUSE, dwFlags, 20, anychat.GetUserName(-1));
  19.                                         }
  20.                                 }).setMessage(userStr+":请求通话").create();
  21.                          dialogRequest.show();
复制代码
三、呼叫请求回复
B收到“请求指令之后”之后,可以回复A的请求。
1、同意通话,调用
  1.         anychat.VideoCallControl(AnyChatDefine.BRAC_VIDEOCALL_EVENT_REPLY, useridA, AnyChatDefine.RETURNCODE_SUCCESS, dwFlags, 10, anychat.GetUserName(-1));
复制代码
其中useridA为用户A的userId,10、anychat.GetUserName(-1)都是用户自定义参数
2、拒绝通话,调用
anychat.VideoCallControl(AnyChatDefine.BRAC_VIDEOCALL_EVENT_REPLY, useridA, AnyChatDefine.RETURNCODE_SESSION_REFUSE, dwFlags, 20, anychat.GetUserName(-1));
其中useridA为用户A的userId,20、anychat.GetUserName(-1)都是用户自定义参数。A端触发OnAnyChatVideoCallEvent,可以得知B拒绝通话
  1.         case AnyChatDefine.BRAC_VIDEOCALL_EVENT_REPLY:
  2.                         switch(dwErrorCode)
  3.                         {
  4.                         case AnyChatDefine.RETURNCODE_SESSION_REFUSE:
  5.                                 showToast("目标用户拒绝会话");
  6.                                 if(dialogCall!=null)
  7.                                         dialogCall.dismiss();
  8.                                 break;
复制代码
3、取消呼叫
A端此时可以取消呼叫,调用
  1. anychat.VideoCallControl(AnyChatDefine.BRAC_VIDEOCALL_EVENT_REPLY, useridB, AnyChatDefine.RETURNCODE_SESSION_QUIT, dwFlags, 30, anychat.GetUserName(-1));
复制代码
B端将触发OnAnyChatVideoCallEvent
  1.         case AnyChatDefine.BRAC_VIDEOCALL_EVENT_REPLY:
  2.                         switch(dwErrorCode)
  3.                         {
  4.                         case AnyChatDefine.RETURNCODE_SESSION_QUIT:
  5.                                 showToast("源用户主动放弃会话");
  6.                                 break;
复制代码
四、会话开始
B端发送“同意会话回复”之后,服务器端将向A、B同时发送“会话开始”指令,A和B将触发OnAnyChatVideoCallEvent
  1. public void OnAnyChatVideoCallEvent(int dwEventType, final int dwUserId,
  2.                         int dwErrorCode, final int dwFlags, final int dwParam, final String userStr) {
  3.                 // TODO Auto-generated method stub
  4.                 switch(dwEventType)
  5.                 {
  6.                 case AnyChatDefine.BRAC_VIDEOCALL_EVENT_START:
  7.                         anychat.LeaveRoom(-1);
  8.                          Intent intent=new Intent();
  9.                            intent.putExtra("UserID",targetUserId);
  10.                            intent.putExtra("ROOMID",dwParam);
  11.                            intent.setClass(RoomActivity.this, VideoActivity.class);
  12.                        startActivity(intent);
  13.                         break;
复制代码
其中dwParam是roomId,A和B收到之后可以进入同一房间进行音视频通话。

五、会话结束
B或者A任何一方发送会话结束指令,调用
  1. anychat.VideoCallControl(AnyChatDefine.BRAC_VIDEOCALL_EVENT_FINISH, userID, 0, 0, 0, "");
复制代码
其中userID为对方的useId.此时A、B将会触发“呼叫结束事件”OnAnyChatVideoCallEvent
  1. public void OnAnyChatVideoCallEvent(int dwEventType, int dwUserId,
  2.                         int dwErrorCode, int dwFlags, int dwParam, String userStr) {
  3.                 // TODO Auto-generated method stub
  4.                 public void OnAnyChatVideoCallEvent(int dwEventType, final int dwUserId,
  5.                         int dwErrorCode, final int dwFlags, final int dwParam, final String userStr) {
  6.                 // TODO Auto-generated method stub
  7.                 switch(dwEventType)
  8.                 {
  9. case AnyChatDefine.BRAC_VIDEOCALL_EVENT_FINISH:
  10.                         Toast.makeText(this, "通话结束",Toast.LENGTH_LONG).show();
  11.                         this.finish();
  12.                 }
复制代码
六、附录,errorcode定义
        public static final int RETURNCODE_SUCCESS=0;
        public static final int RETURNCODE_SESSION_QUIT = 100101;// 源用户主动放弃会话
        public static final int RETURNCODE_SESSION_OFFLINE = 100102;// 目标用户不在线
        public static final int RETURNCODE_SESSION_BUSY = 100103;// 目标用户忙
        public static final int RETURNCODE_SESSION_REFUSE = 100104;// 目标用户拒绝会话
        public static final int RETURNCODE_SESSION_TIMEOUT = 100105;//会话请求超时
        public static final int RETURNCODE_SESSION_DISCONNECT= 100106;// 网络断线
回复 支持 反对

使用道具 举报

0

主题

29

帖子

84

积分

注册会员

Rank: 2

积分
84
发表于 2013-10-11 16:10:57 | 显示全部楼层
廖斌 发表于 2013-9-10 10:55
下面android端为例,展示实现视频呼叫业务逻辑的整个过程
一、设置呼叫回调事件接收
用户收到呼叫请求、 ...

请问实现以上逻辑,需要服务器二次开发吗?
1.如果不需要的话,A呼叫B 执行
anychat.VideoCallControl(AnyChatDefine.BRAC_VIDEOCALL_EVENT_REQUEST, useridB, 0, 0,0, "usernameA")
OnAnyChatVideoCallEvent ()方法无响应.
2.如果需要的话,能否提供代码
谢谢
回复 支持 反对

使用道具 举报

240

主题

2958

帖子

8871

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
8871
发表于 2013-10-11 16:14:21 | 显示全部楼层
您好,服务器端不需要进行二次开发,该业务逻辑可以单独由核心服务器来实现,即可以不倚赖业务服务器。

执行方法“anychat.VideoCallControl”无响应,请确认两边客户端、服务器都是最新版本。
回复 支持 反对

使用道具 举报

0

主题

29

帖子

84

积分

注册会员

Rank: 2

积分
84
发表于 2013-10-11 16:34:56 | 显示全部楼层
admin 发表于 2013-10-11 16:14
您好,服务器端不需要进行二次开发,该业务逻辑可以单独由核心服务器来实现,即可以不倚赖业务服务器。

...

服务器端是最新版本
android客户端是我下载官方demo后修改的
官方demo中点击用户执行以下方法, 但对方无任何提示.
                 Intent intent = new Intent();
                intent.putExtra("UserID", idList.get(position));
                intent.setClass(RoomActivity.this, VideoActivity.class);
                startActivity(intent);,
我修改为下面的方法,请问是否正确.--------
                anychat.VideoCallControl(AnyChatDefine.BRAC_VIDEOCALL_EVENT_REQUEST,
                                Integer.parseInt(idList.get(position)), 0, 0, 0, "usernameA");
谢谢.
回复 支持 反对

使用道具 举报

5

主题

1269

帖子

3677

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3677
发表于 2013-10-11 16:50:45 | 显示全部楼层
KeepGoing2013 发表于 2013-10-11 16:34
服务器端是最新版本
android客户端是我下载官方demo后修改的
官方demo中点击用户执行以下方法, 但对方 ...

可以的。android业务流程描述中的代码还没有更新到网上,还是老的代码
回复 支持 反对

使用道具 举报

0

主题

29

帖子

84

积分

注册会员

Rank: 2

积分
84
发表于 2013-10-11 16:57:48 | 显示全部楼层
廖斌 发表于 2013-10-11 16:50
可以的。android业务流程描述中的代码还没有更新到网上,还是老的代码

回调接收anychat.SetVideoCallEvent(this)也已经设置,但是OnAnyChatVideoCallEvent()方法无响应.
谢谢
回复 支持 反对

使用道具 举报

5

主题

1269

帖子

3677

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3677
发表于 2013-10-11 17:05:04 | 显示全部楼层
您设置的SetVideoCallEvent在什么地方呢?另外最新的核心服务器才支持业务呼叫逻辑,你连接的服务器是什么版本的?
回复 支持 反对

使用道具 举报

0

主题

29

帖子

84

积分

注册会员

Rank: 2

积分
84
发表于 2013-10-11 17:09:02 | 显示全部楼层
廖斌 发表于 2013-10-11 17:05
您设置的SetVideoCallEvent在什么地方呢?另外最新的核心服务器才支持业务呼叫逻辑,你连接的服务器是什么 ...

private void InitialSDK() {
                anychat = new AnyChatCoreSDK();
                anychat.SetBaseEvent(this);
                anychat.SetTextMessageEvent(this);
                anychat.SetVideoCallEvent(this);
        }
服务器版本是v4.8
谢谢
回复 支持 反对

使用道具 举报

240

主题

2958

帖子

8871

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
8871
发表于 2013-10-11 17:20:55 | 显示全部楼层
您好,请将客户端、服务器的log均帖上来我们帮您分析一下,谢谢!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|AnyChat ( 粤ICP备13022410号-1 )  

GMT+8, 2020-2-22 00:13 , Processed in 0.207236 second(s), 25 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表