thrift源码(三)服务端

简单的服务端实现 TThreadPoolServer

TProcessor

和TServiceClient接口类似,TProcessor是thrift为服务端生成代码时要实现的接口,定义了服务端根据客户端请求调用本地接口实现的过程。

HelloService.Processor代码如下:

iface_是服务启动时,传入的HelloServiceImpl对象实例
processMap_用来保存HelloService定义的方法。
process()函数会根据方法名,找到对应的ProcessFunction实现类,调用ProcessFunction.process()方法。如果没有则返回异常。
至于方法参数和结果,以helloString()方法为例,helloString_result和helloString_args和thrift客户端使用的类是同一个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
protected final HashMap<String, ProcessFunction> processMap_ = new HashMap<String, ProcessFunction>();
private Iface iface_;

public Processor(Iface iface) {
iface_ = iface;
processMap_.put("helloString", new helloString());
processMap_.put("helloInt", new helloInt());
processMap_.put("helloBoolean", new helloBoolean());
processMap_.put("helloVoid", new helloVoid());
processMap_.put("helloNull", new helloNull());
}
public boolean process(TProtocol iprot, TProtocol oprot) throws TException {
TMessage msg = iprot.readMessageBegin();
ProcessFunction fn = processMap_.get(msg.name);
if (fn == null) {
TProtocolUtil.skip(iprot, TType.STRUCT);
iprot.readMessageEnd();
TApplicationException x = new TApplicationException(TApplicationException.UNKNOWN_METHOD,
"Invalid method name: '" + msg.name + "'");
oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));
x.write(oprot);
oprot.writeMessageEnd();
oprot.getTransport().flush();
return true;
}
fn.process(msg.seqid, iprot, oprot);
return true;
}

TThreadPoolServer调用时序图

启动服务端的代码代码如下:

1
2
3
4
5
6
7
8
9
10
// 设置服务端口为 7911
TServerSocket serverTransport = new TServerSocket(7911);
// 设置协议工厂为 TBinaryProtocol.Factory
TBinaryProtocol.Factory proFactory = new TBinaryProtocol.Factory();
// 关联处理器与 Hello 服务的实现
TProcessor processor = new HelloService.Processor(new HelloServiceImpl());
TServer server = new TThreadPoolServer(processor, serverTransport,
proFactory);
System.out.println("Start server on port 7911...");
server.serve();

TThreadPoolServer工作的时序图很简单,和所有服务端套接字程序一样,执行listen(),accept(),read(),write()的流程,使用的I/O模型是每处理一个客户端请求就从线程池中取出一个线程。

时序图1

Xianfeng Song wechat
关注公众号,第一时间更新