加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

SIP(20):exosip_event的循环处理

(2012-10-26 09:44:24)
标签:

sip

多线程

分类: SIP探索之路

前几天编程虽然一直都成功,但是有个问题就是我们总是在重复开启eXosip_event_wait(0,50)函数,现在打算围绕eXosip_event_wait展开,即eXosip_event_wait一直处以循环跑。

 

--------海xx程序研究--------

参看下海xx的程序,是如下所示的,在imsUA.c中的main函数中有如下函数:

 

g_timeout_add (200, get_exosip_events, imsUA);

 

解释如下:

g_timeout_add (guint interval,
               GSourceFunc function,
               gpointer data);

第一个参数是间隔的毫秒数,第二个参数是定时后的callback,第三个是传递给callback的数据。海xx的程序是指每隔200ms进行如下流程,对不同的事件进行不同的响应。

int get_exosip_events(gpointer main_window)
{
 eXosip_event_t *je;
 char display[500] = "";
  eXosip_lock();
 eXosip_unlock();
 
 
 if((je = eXosip_event_wait(0,50)) != NULL)
 {
  
  // fprintf(stderr, "Event type: %d %s\n", je->type, je->textinfo);

  imsua_display_event_info(je);

  if (je->type == EXOSIP_CALL_INVITE)
  {
   ims_process_incoming_invite(je);
  }
  else if (je->type == EXOSIP_CALL_REINVITE)
  {
   ims_process_incoming_reinvite(je);
  }
  else if (je->type == EXOSIP_CALL_RINGING)
  {
   ims_process_18x(je);
  }
  else if (je->type == EXOSIP_CALL_GLOBALFAILURE)
  {
   ims_process_released_call(je);
  }
  else if (je->type == EXOSIP_CALL_CLOSED)
  {
   ims_process_released_call(je);
  }
  else if (je->type == EXOSIP_CALL_ANSWERED)
  {
   ims_process_200ok(je);
   
  }
  else if (je->type == EXOSIP_CALL_RELEASED)
  {
   ims_process_released_call(je);

  }
  else if (je->type ==  EXOSIP_CALL_CANCELLED)
  {
    ims_process_released_call(je);
  }
  else if (je->type == EXOSIP_CALL_ACK)
  {
   ims_process_ack(je);
  }
  else if (je->type == EXOSIP_CALL_MESSAGE_REQUESTFAILURE)
  {
   ims_process_released_call(je); 
  }
  else if (je->type == EXOSIP_CALL_REQUESTFAILURE)
  {
   set_display("Call released");
  }
  else if (je->type == EXOSIP_CALL_SERVERFAILURE)
  {
   set_display("Call released by server");
  }
  else if (je->type == EXOSIP_CALL_MESSAGE_NEW)
  {
   if (MSG_IS_PRACK(je->request))
    ims_process_prack(je);
   else if (MSG_IS_UPDATE(je->request))
    ims_process_update(je);
   else if (MSG_IS_INFO(je->request))
    common_process_info(je);
  }
  else if (je->type == EXOSIP_CALL_MESSAGE_ANSWERED)
  {
   if (MSG_IS_BYE(je->request))
    ims_process_released_call(je);
   else if (MSG_IS_UPDATE(je->request) || MSG_IS_PRACK(je->request))
    ims_process_2xx(je);
  }
  else if (je->type == EXOSIP_MESSAGE_NEW)
   
   if (MSG_IS_MESSAGE(je->request))
   {
    
    char sending_ui[50];
    strcpy(sending_ui,(((je->request)->to)->url)->username);
    strcat(sending_ui,"@");
    strcat(sending_ui,(((je->request)->to)->url)->host);
          
    char *temp;
    temp = strstr(pref->impu,":") + 1;
          
    if(strcmp(sending_ui,temp)==0)
    {
     ims_start_im_session(je);
    }
    
   }
   else if (MSG_IS_BYE(je->request))
   {
    set_display("Call ended");
   }
   
  }
  else if(je->type == EXOSIP_MESSAGE_REQUESTFAILURE)
  {

  }
  else if(je->type == EXOSIP_MESSAGE_ANSWERED)
  {

  }
  else if(je->type == EXOSIP_REGISTRATION_SUCCESS)
  {

   if(is_message_deregister == 1)
   {
    registered = NOT_REGISTERED;

    is_message_deregister = 0;
    
    sprintf(display, "Deregistered with %s",pref->realm);
    set_display(display);
     
    sprintf(display,"Not registered");
    set_status_bar(display);

    watchers_remove_all_watchers();

    num_associated_uris = 0;
    
   }
   else
   {
    registered = REGISTERED;
    ims_process_registration_200ok(je);

   }
  }
  else if(je->type == EXOSIP_REGISTRATION_FAILURE)
  {

   if((je->response)== NULL)
   {
    set_display("Registration failed for unknown reason\nMost probably incorrect credentials\n\nCheck Preferences");
   }
   else if(((je->response)->status_code == 403))
   {
    set_display("Invalid user name\n\nCheck Preferences");
   }
   else if(((je->response)->status_code == 401))
   {
    ims_process_401(je);
   }
   else if(((je->response)->status_code == 404) || ((je->response)->status_code == 407))
   {
 
    set_display("Error with credentials\n\nCheck Preferences");
   }
   else
   {
    set_display("Registration failed for unknown reason\n\nMost probably incorrect credentials\nCheck Preferences");
   }
   
  }
  else if(je->type == EXOSIP_REGISTRATION_REFRESHED)
  {
   set_display("Regsitration Refreshed");
   registered = REGISTERED;
  }
  else if(je->type == EXOSIP_REGISTRATION_TERMINATED)
  {
  }
  else if(je->type == EXOSIP_SUBSCRIPTION_ANSWERED)
  {

  }
  else if (je->type == EXOSIP_SUBSCRIPTION_NOTIFY)
  {
   ims_process_notify(je);
   
  }
  else if (je->type == EXOSIP_SUBSCRIPTION_REQUESTFAILURE)
  {

  }
  else if(((je->response)->status_code == 302))
  {
   ims_process_302(je);
  }
  else
  {
  }
  
 }

 return TRUE;
}

----------------------------

 

好了,GTK有上述函数,那现在需要在VC++上实现需要使用线程函数,孙鑫教程中使用了CreateThread函数,但是网上更加推荐_beginthreadex,函数,使用起来也非常简单,由于这个日志也算是回炒了,现在看起来也没什么,但是当时没有涉猎线程的概念,成功的意义倒是非常大。

原始的Dos的线程这里已经丢失了,就贴下在MFC的线程函数,注意加上<process.h>:

//---线程启动---

HANDLE h_event;

h_event = (HANDLE)_beginthreadex(NULL,0,Event_react,m_hWnd,0,NULL); 

CloseHandle(h_event);

//线程函数

unsigned __stdcall Event_react( void* pArguments )

{

  。。。。。

}

即可。

使用了事件响应线程之后,让后台不断的读取到来事件并作出响应,就可以实现客户端和服务端的统一。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有