这一部分主要实现了底层IO通信,还涉及到通信服务器的堵塞、非堵塞、单线程、多线程等运行模式,所以实现比较复杂。这一部分涉及到的类的关系图如下:
由上面的类关系图可以看出,这一部分的类关系比较复杂,复杂的不是继承关系,而是相互之间的依赖关系。因为服务器需要处理很多的任务,也需要处理多个客户端的连接,这就涉及到多线程编程以及多线程之间通信及并发的情况。这一部分涉及到的并发编程的类容将在后面章节单独分析,本章主要介绍服务器模型和IO通信的具体细节。
所有具体的服务器模型实现类都从一个共同的基类继承,这个基类就是本节介绍的TServer类,这个类又从Runnable继承,Runnable类是一个实现多线程的抽象类,类似java里面的。下面分别从成员变量的定义、构造函数和其他相关函数介绍TServer定义的功能。
1.成员变量定义
一个类的成员变量定义基本上能够体现出类的属性,首先看看主要成员变量的定义及其作用:
boost::shared_ptr<TProcessorFactory> processorFactory_;//处理层的对象生成工厂对象
boost::shared_ptr<TServerTransport> serverTransport_;//服务器传输对象
boost::shared_ptr<TTransportFactory> inputTransportFactory_;//输入传输层工厂对象
boost::shared_ptr<TTransportFactory> outputTransportFactory_;//输出传输层工厂对象
boost::shared_ptr<TProtocolFactory> inputProtocolFactory_;//输入协议层工厂对象
boost::shared_ptr<TProtocolFactory> outputProtocolFactory_;//输出协议层工厂对象
boost::shared_ptr<TServerEventHandler> eventHandler_;//服务器事件处理对象类
Thrift的服务器类基本上把其他所有层的功能综合起来了,这样每一个不同的服务器模型实现都可以组装不同的处理层逻辑(主要根据用户定义的逻辑接口定义语言代码字段生成的一层)、协议层和传输层,在加上一个单独处理事件的类,整个服务器就相当的强大而且灵活。这些对象都是抽象基类的对象,需要在实例化的时候依赖具体的子类实现。
2.构造函数
构造函数的主要作用就是初始化上一节定义的成员变量,提供了多个版本的构造函数,根据需要具体初始的成员变量定义,例如如果需要指定一个具体的处理层的工厂对象以便生成对应需要的处理层类对象构造函数定义如下:
template<typename ProcessorFactory>
TServer(const boost::shared_ptr<ProcessorFactory>& processorFactory,
const boost::shared_ptr<TServerTransport>& serverTransport,
const boost::shared_ptr<TTransportFactory>& transportFactory,
const boost::shared_ptr<TProtocolFactory>& protocolFactory,
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)):
processorFactory_(processorFactory),
serverTransport_(serverTransport),
inputTransportFactory_(transportFactory),
outputTransportFactory_(transportFactory),
inputProtocolFactory_(protocolFactory),
outputProtocolFactory_(protocolFactory) {}
构造函数都是模板函数,但是只会针对具体类的对象特化,例如上面代码就只会针对模板参数是TProcessorFactory类进行特化,做到这一点的是宏定义:
THRIFT_OVERLOAD_IF(ProcessorFactory, TProcessorFactory)//如果模板参数ProcessorFactory能够转换为TProcessorFactory那么就特化这个版本函数
------>#define THRIFT_OVERLOAD_IF(T, Y) \
THRIFT_OVERLOAD_IF_DEFN(T, Y) = NULL
------>#define THRIFT_OVERLOAD_IF_DEFN(T, Y) \
typename ::boost::enable_if<typename ::boost::is_convertible<T*, Y*>::type, \
void*>::type
这个是利用了boost库的功能,具体参考boost库帮助文档。还有好几个这样的构造函数,只是参数不同而已,没有传递的参数就new一个默认的对象来初始化,以后调用函数来设置就可以了,下面就介绍这些函数。
3.Get和Set函数
Get和Set函数主要针对一些成员变量进行赋值和取值,例如针对输入协议类对象的设置和获取函数如下定义和实现:
void setInputProtocolFactory(boost::shared_ptr<TProtocolFactory> inputProtocolFactory) {
inputProtocolFactory_ = inputProtocolFactory;
}
boost::shared_ptr<TProtocolFactory> getInputProtocolFactory() {
return inputProtocolFactory_;
}
其他成员变量也都有类似的函数对。
4.其他函数
这些函数主要是实现具体服务器功能的函数了,每一个具体的服务器模型类都需要实现以满足一个服务器的基本需求,当然实现不同功能差别也很大,例如执行异步多线程、连接池、线程池等。
先重点介绍一个获取处理逻辑类对象的函数,定义如下:
boost::shared_ptr<TProcessor> getProcessor(
boost::shared_ptr<TProtocol> inputProtocol,
boost::shared_ptr<TProtocol> outputProtocol,
boost::shared_ptr<TTransport> transport) {
TConnectionInfo connInfo;
connInfo.input = inputProtocol;
connInfo.output = outputProtocol;
connInfo.transport = transport;
return processorFactory_->getProcessor(connInfo);//调用具体处理层工厂类的相应函数获取
}
这里又出现一个新的结构体连接信息对象TConnectionInfo ,主要作用就是记录输入输出协议类和服务器传输对象。这个函数根据输入输出协议类和传输层对象构造一个具体的处理类对象(在前已经具体介绍过实现和功能了)。其他重要函数定义如下:
virtual ~TServer() {}
virtual void serve() = 0;
virtual void stop() {}
// Allows running the server as a Runnable thread
virtual void run() {
serve();
}
每一个具体服务器模型子类都会重点实现这些函数,特别是serve函数。Run函数就是线程运行时执行的这个函数开始提供服务了。