thrift 从 0.9.1版本开始,可以完美支持 go 语言,可以完美的实现跨语言的 rpc 调用了。下面以 go 和 java 语言相互调用为例。
- 编辑协议文件,go 语言示例
/** example.thrift */ namespace go example service transdata { bool sendMsg(1: string msgJson), }
- 下载thrift,用于生成协议库文件
下载地址 http://www.apache.org/dyn/closer.cgi?path=/thrift/0.11.0/thrift-0.11.0.exe
生成库文件 thrift.0.11.0.exe -r --gen go example.thrift
- go 语言客户端和服务端示例代码
/** thrift_example.go */
package thrift import ( "fmt" "git.apache.org/thrift.git/lib/go/thrift" "os" "context" "log" "net" "awesome-go/src/service/thrift/gen-go/example" ) const ( HOST = "localhost" PORT = "19090" ) type TransdataImpl struct { } func (trandata *TransdataImpl) SendMsg(ctx context.Context, msgJson string) (r bool, err error){ fmt.Println("-->SendMsg Call:", msgJson) return true, nil } func Server() { transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory()) protocolFactory := thrift.NewTBinaryProtocolFactoryDefault() //protocolFactory := thrift.NewTCompactProtocolFactory() serverTransport, err := thrift.NewTServerSocket(net.JoinHostPort(HOST, PORT)) if err != nil { fmt.Println("Error!", err) os.Exit(1) } handler := &TransdataImpl{} processor := example.NewTransdataProcessor(handler) server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) fmt.Println("thrift server in", net.JoinHostPort(HOST, PORT)) server.Serve() } func Client() { tSocket, err := thrift.NewTSocket(net.JoinHostPort(HOST, PORT)) if err != nil { log.Fatalln("tSocket error:", err) } transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory()) transport, _ := transportFactory.GetTransport(tSocket) protocolFactory := thrift.NewTBinaryProtocolFactoryDefault() client := example.NewTransdataClientFactory(transport, protocolFactory) if err := transport.Open(); err != nil { log.Fatalln("Error opening:", HOST + ":" + PORT) } defer transport.Close() d, err := client.SendMsg(nil,"test string") fmt.Println(d) }
- go 语言测试代码
/** thrift_example_test.go */
package thrift import "testing" func ClientTest(t *testing.T) { Client() } func ServerTest(t testing.T) { Server() }
- java 协议文件示例
namespace go service.thrift service Transdata { bool sendMsg(1: string msgJson), }
- 生成java 协议库文件
生成库文件 thrift.0.11.0.exe -r --gen java example.thrift
- java 服务端示例
package service.thrift; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TBinaryProtocol.Factory; import org.apache.thrift.server.TNonblockingServer; import org.apache.thrift.server.TServer; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TNonblockingServerTransport; import org.apache.thrift.transport.TTransportException; /** * @author zhengqian */ public class Server { public static void StartSimpleServer(Transdata.Processor<ExampleHandler> processor) { TNonblockingServerTransport serverTransport = null; try { serverTransport = new TNonblockingServerSocket(19090); } catch (TTransportException e) { e.printStackTrace(); } Factory protFactory = new TBinaryProtocol.Factory(true, true); //TCompactProtocol.Factory protFactory = new TCompactProtocol.Factory(); TNonblockingServer.Args args = new TNonblockingServer.Args( serverTransport); args.processor(processor); args.protocolFactory(protFactory); TServer server = new TNonblockingServer(args); System.out.println("Start server on port 19090 ..."); server.serve(); } public static void main(String[] args) { StartSimpleServer(new Transdata.Processor<ExampleHandler>(new ExampleHandler())); } }
- java 客户端代码示例
package service.thrift; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; /** * @author zhengqian */ public class Client { public static void main(String[] args) { try { TTransport transport = new TFramedTransport(new TSocket("localhost", 19090)); TProtocol protocol = new TBinaryProtocol(transport); Transdata.Client client = new Transdata.Client(protocol); transport.open(); System.out.println(client.sendMsg("test string")); transport.close(); } catch (TTransportException e) { e.printStackTrace(); } catch (TException x) { x.printStackTrace(); } } }
- 两个语言版本的 server / client 随意组合,都可以相互调用。
- 补充,如果两端使用的 thrift 版本不一致,也可以调用,测试一端使用 0.9.3 版本,一端使用 0.11.0 版本,可正常相互调用。不用担心旧服务不兼容的问题。