libthrift0.9.0解析(二)之TSimpleServer

TSimpleServer简单实现Tserver,代码如下。

/**

 * Simple singlethreaded server for testing.

 *

 */

public class TSimpleServer extends TServer {



  private static final Logger LOGGER = LoggerFactory.getLogger(TSimpleServer.class.getName());



  private boolean stopped_ = false;



  public TSimpleServer(AbstractServerArgs args) {

    super(args);

  }



  public void serve() {

    stopped_ = false;

    try {

      serverTransport_.listen(); // 开启监听

    } catch (TTransportException ttx) {

      LOGGER.error("Error occurred during listening.", ttx);

      return;

    }



    // Run the preServe event

    if (eventHandler_ != null) {

      eventHandler_.preServe(); // 前处理切入

    }



    setServing(true);



    while (!stopped_) {

      TTransport client = null;

      TProcessor processor = null;

      TTransport inputTransport = null;

      TTransport outputTransport = null;

      TProtocol inputProtocol = null;

      TProtocol outputProtocol = null;

      ServerContext connectionContext = null;

      try {

        client = serverTransport_.accept(); // 获得一个client transport

        if (client != null) { // 以下代码根据获取的client transport层层封装

          processor = processorFactory_.getProcessor(client); // 根据client获取processor

          inputTransport = inputTransportFactory_.getTransport(client); // 根据client获取input transport

          outputTransport = outputTransportFactory_.getTransport(client); // 根据client获取output transport

          inputProtocol = inputProtocolFactory_.getProtocol(inputTransport); // 根据input transport获取input protocol

          outputProtocol = outputProtocolFactory_.getProtocol(outputTransport); // 根据output transport获取output protocol

          if (eventHandler_ != null) {// 处理前切入eventHandler根据input/output protocol生成connectionContext

            connectionContext = eventHandler_.createContext(inputProtocol, outputProtocol);

          }

          while (true) {// 一直循环处理同一个用户的请求,processor.process永远返回true,只有抛出异常时(即用户端主动关闭连接)才会继续接收下一个用户的请求。

            if (eventHandler_ != null) {// 切入eventHandler处理前面生成的connectionContext

              eventHandler_.processContext(connectionContext, inputTransport, outputTransport);

            }

            if(!processor.process(inputProtocol, outputProtocol)) {// 调用processor对input/output protocol进行处理

              break;

            }

          }

        }

      } catch (TTransportException ttx) {

        // Client died, just move on

      } catch (TException tx) {

        if (!stopped_) {

          LOGGER.error("Thrift error occurred during processing of message.", tx);

        }

      } catch (Exception x) {

        if (!stopped_) {

          LOGGER.error("Error occurred during processing of message.", x);

        }

      }



      if (eventHandler_ != null) {

        eventHandler_.deleteContext(connectionContext, inputProtocol, outputProtocol);

      }



      if (inputTransport != null) {

        inputTransport.close();

      }



      if (outputTransport != null) {

        outputTransport.close();

      }



    }

    setServing(false);

  }



  public void stop() {

    stopped_ = true;

    serverTransport_.interrupt();

  }

}

 

首先,开启监听,然后在处理之前面向切面切入前处理流程 eventHandler_.preServe();最后进入接收处理流程。

处理时关键看第54行processor.process()函数。

TProcessor为一单接口,仅含process方法。其子类thrift不再提供,而是根据用户自定义的thrift IDL文件自动生成。然而thrift提供了一个抽象类TBaseProcessor<I>封装了一些常用的实现,该类实现了TProcessor接口,框架自动生成的Processor都继承了该基类。

TBaseProcessor<I>代码如下:

 

public abstract class TBaseProcessor<I> implements TProcessor {

  private final I iface; // 真正的处理函数实现

  private final Map<String,ProcessFunction<I, ? extends TBase>> processMap;



  protected TBaseProcessor(I iface, Map<String, ProcessFunction<I, ? extends TBase>> processFunctionMap) {

    this.iface = iface;

    this.processMap = processFunctionMap;

  }



  public Map<String,ProcessFunction<I, ? extends TBase>> getProcessMapView() {

    return Collections.unmodifiableMap(processMap);

  }



  @Override

  public boolean process(TProtocol in, TProtocol out) throws TException {

    TMessage msg = in.readMessageBegin(); // 获取请求信息,主要包含函数名信息。

    ProcessFunction fn = processMap.get(msg.name); // 根据函数名信息获取相应的处理函数。

    if (fn == null) { // 若没有相关的处理函数,写入异常并返回。

      TProtocolUtil.skip(in, TType.STRUCT);

      in.readMessageEnd();

      TApplicationException x = new TApplicationException(TApplicationException.UNKNOWN_METHOD, "Invalid method name: '"+msg.name+"'");

      out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));

      x.write(out);

      out.writeMessageEnd();

      out.getTransport().flush();

      return true;

    }

    fn.process(msg.seqid, in, out, iface); // 处理请求

    return true;

  }

}

 

ProcessFunction为一抽象类,其子类也是根据IDL自动生成。与IDL中的函数一一对应,为代理处理器。

TBase为IDL中定义的types的基类。T封装了处理函数的参数信息,其子类也是框架根据IDL自动生成。

public abstract class ProcessFunction<I, T extends TBase> {

  private final String methodName;



  private static final Logger LOGGER = LoggerFactory.getLogger(ProcessFunction.class.getName());



  public ProcessFunction(String methodName) {

    this.methodName = methodName;

  }



  public final void process(int seqid, TProtocol iprot, TProtocol oprot, I iface) throws TException {

    T args = getEmptyArgsInstance(); // 获取一个空的参数封装

    try {

      args.read(iprot); // 从input protol中读取所有参数到args中

    } catch (TProtocolException e) {

      iprot.readMessageEnd();

      TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage());

      oprot.writeMessageBegin(new TMessage(getMethodName(), TMessageType.EXCEPTION, seqid));

      x.write(oprot);

      oprot.writeMessageEnd();

      oprot.getTransport().flush();

      return;

    }

    iprot.readMessageEnd(); // 读取参数完毕

    TBase result = null;



    try {

      result = getResult(iface, args); // 获取处理结果

    } catch(Throwable th) {

      LOGGER.error("Internal error processing " + getMethodName(), th);

      TApplicationException x = new TApplicationException(TApplicationException.INTERNAL_ERROR, 

        "Internal error processing " + getMethodName());

      oprot.writeMessageBegin(new TMessage(getMethodName(), TMessageType.EXCEPTION, seqid));

      x.write(oprot);

      oprot.writeMessageEnd();

      oprot.getTransport().flush();

      return;

    }



    if(!isOneway()) {// true表示单向操作不许要返回信息,即函数为void类型。false表示需要返回值,则启用output protol写入结果。

      oprot.writeMessageBegin(new TMessage(getMethodName(), TMessageType.REPLY, seqid));

      result.write(oprot);

      oprot.writeMessageEnd();

      oprot.getTransport().flush();

    }

  }



  protected abstract boolean isOneway();



  public abstract TBase getResult(I iface, T args) throws TException;



  public abstract T getEmptyArgsInstance();



  public String getMethodName() {

    return methodName;

  }

}

 到此为止,基本了解了libthrift的大致框架。在处理函数中主要是与protocol打交道,protocol又是根据input/output transport生成,而input/output transport又是根据client transport生成。总形成三层结构,底层是client transport由server transport的accept函数获得,中层是input/output transport ,顶层是input/output protocol。然而三层之间并不是完全透明不可见的,典型如oprot.getTransport().flush() 对上层暴露了底层,也无伤大雅。

下节介绍protocol以及transport。

你可能感兴趣的:(server)