UniMedia 6S级电话语音中间件典型应用-电话QQ 
                    [附源码]
                  
                   2009/05/11
                  1.应用场景
                    电信增值应用。客户打电话进入系统,按键选择聊天室,或者自动查找匹配的用户,进行一对一的聊天。
                  
                  2.源码片段
                  
                    假定呼入电话,听到提示音,按键为1的为等待聊天用户,电话呼入按键为2的为主动寻找等待聊天的用户
                  
                  //全局变量定义
                  
                  SCPMANAGER g_SCPManager
                  CALL g_TheCall
                  int g_iTaskID
                  
                  sub main(LIST& cpl)
                  {
                  int iCallID, iRet
                  
                  //注册系统错误处理函数
                  EventMap(INF_SYS_ERROR, OnSysError, 0)
                  //注册挂机通知处理函数
                  EventMap(INF_CTI_ONHOOK, OnCallEndInform, 0)
                  //注册被路由通知处理函数
                  EventMap(INF_CTI_ROUTED, OnRoutedInform, 0)
                  //注册取消路由通知处理函数
                  EventMap(INF_CTI_UNROUTED, OnUnroutedInform, 0)
                  //注册异步结束通知处理函数
                  EventMap(INF_SYS_ASYNCFINISHED, OnAsyncFinishedInform, 0)
                  
                  //在BOOT进程启动该进程时,参数是按照CALLID、ANO、BNO,UUD顺序先后存放在参数列表cpl中
                  //根据业务需要取出参数值
                  
                  //获得命令行参数的callid
                  cpl.GetItem(0, iCallID, iRet)
                  Log(DBG, "Call Income: CallID=", iCallID)
                  
                  //根据对象ID获得当前Call对象
                  g_SCPManager.FindCallByID(iCallID, g_TheCall, iRet)
                  //设置Call对象的业务处理进程ID为当前进程
                  g_TheCall.AttachCurrentProcess(iRet)
                  //应答CALL
                  g_TheCall.Answer(iRet)
                  
                  
                  //来话聊天业务处理过程:
                  //来话应答成功后,首先进行放音收码,在分析用户的按键
                  // 如果用户按键为"1",则假定用户为等候交谈的客户,设置业务参数名值对为("Number"、"Waiting"),用户听音乐等待其它用户的交谈申请
                  // 如果用户按键为"2",则假定用户为主动寻找交谈的客户,则从业务参数名值对为("Number"、"Waiting")的等待用户中查找一个进行交谈,并把等待呼叫的名值对该为("Number"、"Connecting")
                  // 如果用户按键为其它,则在循环播放收码
                  while(true)
                  {
                  //同步循环放音收码
                  string sDigits,sTermChar
                  g_TheCall.PlayReceiveDTMF(true, "welcome.vox", 1, "*", sTermChar, 
                  sDigits, -1, iRet)
                  
                  switch(sDigits)
                  {
                  case("1")
                  //等待被连接
                  Log(DBG, "Playing wait music to Income Call(", iCallID, ").")
                  g_TheCall.Play(true, true, "musichold.vox", g_iTaskID, iRet)
                  //设置呼叫对象的业务名值对
                  g_TheCall.SetParam("Number", sDigits, iRet)
                  //注册被连接事件函数
                  EventMap(INF_CTI_ROUTED, OnRoutedInform, 1)
                  
                  //无限等待(直到用户主动挂机)
                  Wait(-1)
                  break
                  
                  case("2")
                  //设置呼叫对象为查找用户的标志
                  g_TheCall.SetParam("Number", sDigits, iRet)
                  //查找空闲等候用户,主动进行连接
                  Log(DBG, "Matching user(", iCallID, ")...")
                  
                  //查找交谈对象并进行连接操作,实现通话交流
                  MatchWaitingUser(g_TheCall)
                  
                  //无限等待(直到用户主动挂机)
                  Wait(-1)
                  break
                  
                  default
                  Log(DBG, "用户按键其它码,需重新收码,Digits=", sDigits)
                  break
                  }//end of Switch
                  }// end of While
                  
                  Log(DBG, "Finished. Bye.")
                  }
                  
                  //查找函数的业务处理过程:
                  //首先给主动查找用户播放等待提示语音
                  //然后根据呼叫对象的名值对从全局呼叫对象实例管理器中查找等待呼叫
                  //如果成功找到,则停止当前呼叫的提示语音,主动进行连接通话操作
                  //如果没有找到,则等待1秒钟在循环查找
                  sub MatchWaitingUser(CALL& call)
                  {
                  int iRet,iTaskID
                  
                  //异步循环放音
                  call.Play(true, true, "waiting.vox", iTaskID, iRet)
                  
                  
                  while(true)
                  {
                  CALL callWait
                  //根据名值对查找等待呼叫对象
                  g_SCPManager.FindCallByParam("Number", "1", callWait, iRet)
                  if (iRet == RET_SUCC)
                  {
                  //重新设置等待连接呼叫的名值对
                  callWait.SetParam("Number","Connecting",iRet)
                  
                  //找到等待用户,停止当前呼叫的语音提示
                  call.StopOP(iTaskID, iRet)
                  
                  //主动连接两个CALL
                  call.ConnectCall(callWait, iRet)
                  break
                  }
                  else
                  {
                  //没有找到,1000毫秒后继续寻找
                  Wait(1000)
                  }
                  }//end of while
                  }
                  
                  //Chat工程中所有事件处理函数实现
                  
                  //错误处理函数
                  sub OnSysError(int tag)
                  {
                  Log(ERR, "System error: ", __LASTERRSTR__)
                  }
                  
                  //挂机通知处理函数
                  sub OnCallEndInform(int tag, CALL& call)
                  {
                  Log(INF, "OnHooked. CallID=", call.CallID)
                  Log(INF, "Exit...")
                  Exit("挂机退出")
                  }
                  
                  //被路由通知处理函数
                  sub OnRoutedInform(int tag, CALL& call1, CALL& call2)
                  {
                  Log(INF, "Routed. CallID1=", call1.CallID, " CallID2=", call2.CallID)
                  
                  int iRet
                  string paraValue
                  //在连接前已经把等待呼叫的名值对的值由1改为Connecting
                  call1.GetParam("Number", paraValue, iRet)
                  if (paraValue == "Connecting")
                  {
                  //call1如果是被连接的等待用户,需要停止它已经在播放的等候音乐
                  call1.StopOP(g_iTaskID, iRet)
                  }
                  }
                  
                  //取消路由通知处理函数
                  sub OnUnroutedInform(int tag, CALL& call1, CALL& call2)
                  {
                  Log(INF, "Unrouted. CallID1=", call1.CallID, " CallID2=", call2.CallID)
                  }
                  
                  //异步结束通知处理函数
                  sub OnAsyncFinishedInform(int tag, CALL& call, int optype, int 
                  taskid, int ret)
                  {
                  if (ret == RET_SUCC)
                  {
                  Log(INF, "异步结束OK. CallID=", call.CallID, " optype=", optype, 
                  " taskid=", taskid)
                  }
                  else
                  {
                  Log(INF, "异步结束FAIL. CallID=", call.CallID, " optype=", optype, 
                  " taskid=", taskid)
                  }
                  } 
                  CTI论坛报道
                  
 相关链接: