首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

libjingle源码分析之二:Thread跟SocketServer

2012-11-10 
libjingle源码分析之二:Thread和SocketServer摘要本文主要分析了libjingle源码中的Thread和SocketServer模

libjingle源码分析之二:Thread和SocketServer

摘要

      本文主要分析了libjingle源码中的Thread和SocketServer模块。同时,给出一个使用Thread模块的使用示例。

概述

      libjingle源码中,Thread和SocketServer模块的原理如下图所示。整个模型实际上是一个消息模型,Thread主要负责处理消息,MessageQue表示的是当前的消息队列,MessageHandler由用户用来定义处理消息的动作。而ThreadManager为单实例,可以获取当前的Thread,这样用户可以往当前的Thread中投递消息。SocketServer代表的是用来侦听Socket的服务,它是一个独立的模块。

libjingle源码分析之二:Thread跟SocketServer

      消息的处理流程主要由Thread负责。上图中有两条处理流程,分别用两根带箭头的线表示。左边箭头的处理流程为:当消息队列中没有消息时,Thread将控制权转交给SocketServer,直到有消息时会通知SocketServer返回到Thread。也就是说Thread优先的是处理消息,在空闲时,会让SocketServer侦听socket。右边的箭头是正常的消息处理流程,获取消息并处理用户定义的对应的OnMessage函数。
      SocketServer模块只是用在libjingle内部,用户并不需要直接使用它。P2P中使用了PhysicalSocketServer作为SocketServer,它的原理如下图所示:

libjingle源码分析之二:Thread跟SocketServer

      PhysicalSocketServer主要是侦听基于本地网卡的socket(libjingle中还有一些伪socket),然后分发socket事件到Dispatcher中。Dispatcher是PhysicalSocketServer的分发体,功能有点类似于MessageHandler。Dispatcher中定义了感兴趣的socket事件和对应的处理。

类的关系

      本文提到的一些类的关系如下图所示。Thread类继承自MessageQue,可以通过Thread类来操作队列消息。PhysicalSocketServer除了实现SocketServer接口之外,还可以添加和删除Dispatcher。熟悉了这些类,基本上就了解Thread模块和SocketServer模块的工作原理。

libjingle源码分析之二:Thread跟SocketServer

使用

      Thread的使用示例参见下面的代码。获取当前线程是通过Thread的Current函数,它会转调ThreadManager对象的CurrentThread函数。由于Thread继承自MessageQue,可以直接通过Thread对象来投递消息,Post函数的第一个参数是OnMessage所处的对象,会被保存于Message对象中。处理消息只要重载MessageHandler的OnMessage函数即可。main函数则调用Thread的Run函数进入默认的消息处理循环,默认的消息处理循环在本示例中就是:循环取消息,调用MessageHandler的OnMessage函数。

#include <string>#include <iostream>#include "talk/base/thread.h"class HelpData : public talk_base::MessageData{public:  std::string info_;};class Police : public talk_base::MessageHandler{public:  enum {    MSG_HELP,  };  void Help(const std::string& info) {    HelpData* data = new HelpData;    data->info_ = info;    talk_base::Thread::Current()->Post(this, MSG_HELP, data);  }  virtual void OnMessage(talk_base::Message* msg) {    switch (msg->message_id) {    case MSG_HELP:      HelpData* data = (HelpData*)msg->pdata;      std::cout << "MSG_HELP : " << data->info_ << std::endl;      break;    }  }};int main(int argc, char** argv){  Police p;  p.Help("Please help me!");  talk_base::Thread::Current()->Run();  return 0;}
        未完待续...

热点排行