Thrift在0.9.1版本之前,一直只提交了對單一接口服務的支持,即一個RPC服務器(對應一個端口)支持一個服務接口的實現。

但是很多時候,我們的服務不能實現在一個接口里,一是接口里的方法越來越多,不好管理和使用;二是根據職責的單一要求,不能類型的方法,不能放在同一接口里。

在 Thrift-0.9.1之前,我們要解決上面的問題,一是通過多個RPC服務器來實現,這個方法必然導致了我們RPC服務器越來越多,管理上麻煩;二是通過其他的一些途徑,如使用netty作為RPC服務器等,這個方法實現上相對麻煩一些,需要去了解netty的知識。

這些方法在這里就不再詳述了。

從Thrift-0.9.1開始,thrift開始提供對多接口服務的支持,使得我們開發多接口RPC服務相對簡單多了。

這里還是給出例子來說明。

首先,我們做了兩個接口定義文件來定義兩個接口:

namespace javacom.eli.test.service

struct Topic

{

    1: i32 uid,

    2: string name,

    3: string content

}

service TopicService

{

    void store(1: Topic topic),

    Topic retrieve(1: i32 uid)

}

 

 

namespace javacom.eli.test.service

struct User

{

    1: i32 uid,

    2: string name,

    3: string blurb

}

service UserService

{

    void store1(1: User user),

    User retrieve1(1: i32 uid)

}

 

 

然后使用Thrift-0.9.1.exe生成相應的JavaBean及接口:

 

 

然后,我們寫兩個接口的實現類:

import org.apache.thrift.TException;

 

import com.eli.test.service.Topic;

import com.eli.test.service.TopicService;

 

public class TopicImpl implements TopicService.Iface{

public void store(Topic topic)throws TException

{

        System.out.println("theinput topic: ");

        System.out.println("id:"+topic.getUid());

        System.out.println("name:"+topic.getName());

        System.out.println("content:"+topic.getContent());

}

public Topic retrieve(int uid)throws TException

{

        System.out.println("theinput uid: "+uid);

        return newTopic(uid,"test","test");

}

 

}

 

 

 

import org.apache.thrift.TException;

 

import com.eli.test.service.User;

import com.eli.test.service.UserService;

 

public class UserImpl implements UserService.Iface{

 

public void store1(User user)throws TException

{

        System.out.println("theinput user: ");

        System.out.println("uid:"+user.getUid());

        System.out.println("name:"+user.getName());

        System.out.println("blur:"+user.getBlurb());

}

public User retrieve1(int uid)throws TException

{

        System.out.println("theinput uid: "+uid);

        return newUser(uid,"tom","123");

}

}

 

 

 

上述工作完成以后,就可以寫服務器代碼了。

服務器代碼與單一接口的服務器代碼最大的不同是使用了“TMultiplexedProcessor”類,通過該類,可以注冊多個接口的服務實現類:

TMultiplexedProcessor processor = new TMultiplexedProcessor();

             

       processor.registerProcessor("TopicService"newTopicService.Processor<TopicService.Iface>(newTopicImpl()));

    processor.registerProcessor("UserService"new UserService.Processor<UserService.Iface>(new UserImpl()));

 

 

其他代碼就跟以前的服務器代碼一樣了。

完整的服務器代碼如下:

TMultiplexedProcessor processor = newTMultiplexedProcessor();

          

           TServerTransport t = new TServerSocket(9090);

           TServer server = new TThreadPoolServer(newTThreadPoolServer.Args(t).processor(processor));

          

           processor.registerProcessor("TopicService"newTopicService.Processor<TopicService.Iface>(newTopicImpl()));

           processor.registerProcessor("UserService"newUserService.Processor<UserService.Iface>(newUserImpl()));

          

//         TSimpleServer server = new TSimpleServer(new Args(t).processor(processor));

 

           System.out.println("the serveris started and is listening at 9090...");

          

        server.serve();

 

 

最后是客戶端代碼了,客戶端代碼的不同之處是引入了“TMultiplexedProtocol”類,它來幫助客戶端區別調用哪個接口:

TMultiplexedProtocol mp1 = new TMultiplexedProtocol(protocol,"TopicService");

                           

    TopicService.Clientservice1 = new TopicService.Client(mp1);

 

完整的客戶端測試代碼如下:

              TSocket transport = new TSocket("localhost",9090);

             

              TBinaryProtocol protocol = new TBinaryProtocol(transport);

             

              TMultiplexedProtocolmp1 = new TMultiplexedProtocol(protocol,"TopicService");

             

              TopicService.Client service1 = newTopicService.Client(mp1);

             

              TMultiplexedProtocolmp2 = new TMultiplexedProtocol(protocol,"UserService");

             

              UserService.Client service2 = newUserService.Client(mp2);

             

              transport.open();

             

              service1.store(new Topic(668,"test topic","just a test!"));

             

              service2.store1(new User(888,"tom","haha"));

             

              System.out.println(service1.retrieve(168));

              System.out.println(service2.retrieve1(999));

             

           transport.close();

 

 

運行服務器代碼和客戶端代碼,則客戶端會打印如下結果:

Topic(uid:168, name:test, content:test)

User(uid:999, name:tom, blurb:123)

 

 

服務器端會打印如下的信息:

the server is started and is listening at 9090...

the input topic:

id: 668

name: test topic

content: just a test!

the input user:

uid: 888

name: tom

blur: haha

the input uid: 168

the input uid: 999

 

通過上面的例子,可以看到,Thrift-0.9.1版本很簡單的解決了多接口服務的問題,隨便說一下,該版本并沒有解決所有語言的多接口實現問題,只是解決了Java和其他幾個語言。請大家在使用的時候,查清楚您使用的語言是否解決了這個問題。