01-Thrift初探
来源:互联网 发布:图书管理数据库系统 编辑:程序博客网 时间:2024/06/07 03:04
- Thrift初探
- 接口文件
- 编写服务器
- 编写客户端
- Go语言版本
- 1 服务器端
- 2 客户端版
- 3 自带Remote客户端
- 简单总结
Thrift初探
目标是编写一个最简单的服务器+客户端
1 接口文件
我们先实现一个最简单的加法服务器:
// MathService.thriftservice MathService { i32 Add(1:i32 A, 2:i32 B)}
使用下载(或编译)的Thrift工具,生成调用代码:
mkdir mysrc // 必须先创建输出目录thrift -o . -out mysrc --gen cpp MathService.thrift //c++源代码thrift -o . -out mysrc --gen go MathService.thrift //golang源代码
目录结构:
C:\xxx\MYSRC│ MathService.cpp│ MathService.h│ MathService_constants.cpp│ MathService_constants.h│ MathService_server.skeleton.cpp│ MathService_types.cpp│ MathService_types.h│└─mathservice │ GoUnusedProtection__.go │ MathService-consts.go │ MathService.go │ └─math_service-remote math_service-remote.go
其中,mathservice目录下是go的代码。根目录下的h和cpp文件是c++代码。
2 编写服务器
其实生成的代码中已经将服务器写好了,MathService_server.skeleton.cpp
如果需要其他特殊需求,可参考这个Demo进行修改。
我们创建一个项目,然后将它们都加入进入进去。
通过Nuget安装Boost-vc140,libevent-vc120, openssl。(后续编译过程很多坑,反而不建议了)
#include "MathService.h"#include <thrift/protocol/TBinaryProtocol.h>#include <thrift/server/TSimpleServer.h>#include <thrift/transport/TServerSocket.h>#include <thrift/transport/TBufferTransports.h>using namespace ::apache::thrift;using namespace ::apache::thrift::protocol;using namespace ::apache::thrift::transport;using namespace ::apache::thrift::server;using boost::shared_ptr;class MathServiceHandler : virtual public MathServiceIf { public: MathServiceHandler() { // Your initialization goes here } // Add 函数的服务器实现 int32_t Add(const int32_t A, const int32_t B) { printf("Add %d + %d\n", A, B); return A+B; }};int main(int argc, char **argv) { int port = 9090; shared_ptr<MathServiceHandler> handler(new MathServiceHandler()); shared_ptr<TProcessor> processor(new MathServiceProcessor(handler)); shared_ptr<TServerTransport> serverTransport(new TServerSocket(port)); shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory()); shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory); server.serve(); return 0;}
Thrift代码的大坑
在编译libthrift时各种通不过,主要有如下问题:
boost开头的文件找不到
解决办法:直接手动指定boost库的头文件所在。一大堆的libThrift函数找不到(这个问题太坑,网上搜不到比较准确的答案)
unresolved external symbol "public: virtual void __cdecl apache::thrift::server::TServerFramework::serve(void)" (?serve@TServerFramework@server@thrift@apache@@UEAAXXZ)
解决办法:将server文件夹中的,TConnectedClient 和 TServerFramework 头文件和cpp都手工添加到libthrift项目中。MathService函数错误
解决办法:在 MathService_server.skeleton.cpp 中,对Add函数进行了实现,但是没有返回值,只需要在Add中增加一个return 返回就行了。
3 编写客户端
#include "MathService.h"#include <thrift/protocol/TBinaryProtocol.h>#include <thrift/transport/TSocket.h>#include <thrift/transport/TBufferTransports.h>using namespace ::apache::thrift;using namespace ::apache::thrift::protocol;using namespace ::apache::thrift::transport;using boost::shared_ptr;int main(int argc, char **argv) { int port = 9090; shared_ptr<TTransport> clientSocket(new TSocket("127.0.0.1", port)); shared_ptr<TTransport> clientTransport(new TBufferedTransport(clientSocket)); shared_ptr<TProtocol> clientProtocol(new TBinaryProtocol(clientTransport)); MathServiceClient client(clientProtocol); try { clientTransport->open(); printf("Open Remote Transport, wait call it!\n"); getchar(); for ( int i=0;i<100;i++ ) { int nRet = client.Add(i, i); printf("[%03d] %d + %d = %d\n", i, i, i, nRet); } } catch (TException& e) { printf("ERROR:%s\n", e.what()); } system("pause"); return 0;}
4 Go语言版本
前提:安装配置好Go环境。本人使用go1.8.3版本测试通过。
需要将mathservice文件夹放到$GOPATH/src
文件夹下,然后在math_service-remote文件夹下编写client.go和server.go文件。
4.1 服务器端
// server.gopackage mainimport ( "fmt" "mathservice" "os" "git.apache.org/thrift.git/lib/go/thrift")const ( NetWorkAddr = "127.0.0.1:9090")type MyMathService struct {}func (this *MyMathService) Add(A int32, B int32) (r int32, err error) { r = A + B err = nil fmt.Println("Add", A, B) return}func main() { handler := &MyMathService{} processor := mathservice.NewMathServiceProcessor(handler) serverTransport, err := thrift.NewTServerSocket(NetWorkAddr) if err != nil { fmt.Println("Error!", err) os.Exit(1) } transportFactory := thrift.NewTBufferedTransportFactory(512) // c++版本默认大小是512 //protocolFactory := thrift.NewTCompactProtocolFactory() protocolFactory := thrift.NewTBinaryProtocolFactoryDefault() server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory) fmt.Println("thrift server in", NetWorkAddr) server.Serve()}
4.2 客户端版
// client.gopackage mainimport ( "mathservice" "fmt" "os" "git.apache.org/thrift.git/lib/go/thrift")func main() { client_socket, _ := thrift.NewTSocket("127.0.0.1:9090") client_transport := thrift.NewTBufferedTransport(client_socket, 512) protocolFactory := thrift.NewTBinaryProtocolFactoryDefault() client := mathservice.NewMathServiceClientFactory(client_transport, protocolFactory) if err := client_transport.Open(); err != nil { fmt.Fprintln(os.Stderr, "Error opening socket", err) os.Exit(1) } defer client_transport.Close() for i := int32(0); i < 100; i++ { nRet, _ := client.Add(i, i) fmt.Println(i, "Add", nRet) } fmt.Println("Over!")}
4.3 自带Remote客户端
自带的math_service-remote.go
是一个很不错的Client学习对象,-P可指定编码方式,-frame可指定帧传输模式,还可以随意指定函数和参数,真的是做的很全面啦!
测试指令go run math_service-remote.go -P binary -h 127.0.0.1 -p 9090 Add 123 888
5 简单总结
使用C++编译使用时,有很多坑存在,作为一个大名鼎鼎的开源项目,文档很少,学习体验很差,真的是让人心烦!相对而言,使用Go编写使用时,体验很不错,唯一的问题就是,文档太少!!!!!!!!
- 01-Thrift初探
- 初探Thrift客户端异步模式
- Thrift入门初探--thrift安装及java入门实例
- Thrift入门初探--thrift安装及java入门实例
- Thrift入门初探--thrift安装及java入门实例
- Thrift入门初探--thrift安装及java入门实例
- Thrift入门初探--thrift安装及java入门实例
- Thrift入门初探--thrift安装及java入门实例
- Thrift入门初探--thrift安装及java入门实例
- Thrift入门初探--thrift安装及java入门实例
- Thrift初探:简单实现C#通讯服务程序
- Thrift初探:简单实现C#通讯服务程序
- Thrift
- thrift
- thrift
- thrift
- Thrift
- Thrift
- linux 后端知识点记录和积累
- 一个页面布局的知识点总结
- HTML 5 音频
- LightOJ
- CSS浮动之三
- 01-Thrift初探
- tomcat 工作原理
- jsp页面放到WEB-INF 跟webroot的区别
- 精通HTML5+CSS3+JavaScript网页设计pdf
- iPhone手机屏幕大小及分辨率
- 快速幂取模
- 【转载】Unity ShaderLab学习总结
- 矩阵相乘
- 浅谈硬链接和软链接