Thrift RPC Example

运行

请直接使用即可,无需拉取任何依赖包。

cd $GOPATH/src

git clone https://github.com/hunterhug/thrift_example.git

go build server.gp
go build client.go ./server
./client

$GOPATH 为环境变量,请替换为你的本地路径。

具体使用,详细介绍

gRPC是Google研究的RPC传输方案,thrift则是facebook, 大家都通过IDL(Interface Definition Language)接口定义语言来规范输入输出。

下载: https://thrift.apache.org/download

Ubuntu 系统安装

sudo apt-get install automake bison flex git libboost-all-dev libevent-dev libssl-dev libtool make pkg-config build-essential g++

tar xvf thrift-0.12.0.tar.gz
./bootstrap.sh
./configure
make
sudo make install
sudo ldconfig

Windows系统请直接安装二进制。

建立 thrift 文件

新建 timeRPC.thrift:

service timeServe {
i32 getCurrtentTime()
}

C++ 服务端

您可以忽略 C++ 部分,直接跳到 Golang 部分。

执行:

thrift --gen cpp timeRPC.thrift

在当前目录下生成一个叫做 "gen-cpp" 的文件夹,里面包含了需要的代码。

├── timeRPC_constants.cpp
├── timeRPC_constants.h
├── timeRPC_types.cpp
├── timeRPC_types.h
├── timeServe.cpp
├── timeServe.h
└── timeServe_server.skeleton.cpp

修改 timeServe_server.skeleton.cpp:

// This autogenerated skeleton file illustrates how to build a server.
// You should copy it to another filename to avoid overwriting it. #include "timeServe.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; class timeServeHandler : virtual public timeServeIf {
public:
timeServeHandler() {
// Your initialization goes here
} int32_t getCurrtentTime() {
// Your implementation goes here
auto t = time(nullptr);
printf("getCurrtentTime: %ld\n", t);
return t;
} }; int main(int argc, char **argv) {
int port = 9090;
::apache::thrift::stdcxx::shared_ptr<timeServeHandler> handler(new timeServeHandler());
::apache::thrift::stdcxx::shared_ptr<TProcessor> processor(new timeServeProcessor(handler));
::apache::thrift::stdcxx::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
::apache::thrift::stdcxx::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
::apache::thrift::stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
return 0;
}

我们实现了 getCurrtentTime这个方法。

编译:

g++ -std=c++11 -o cpp-server timeRPC_constants.cpp timeRPC_types.cpp timeServe.cpp timeServe_server.skeleton.cpp -lthrift

查看:

ldd cpp-server
linux-vdso.so.1 => (0x00007ffee83b4000)
libthrift-0.12.0.so => /usr/local/lib/libthrift-0.12.0.so (0x00007f0200e34000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f0200ab2000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f020089c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f02004d2000)
libssl.so.1.0.0 => /lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007f0200269000)
libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007f01ffe24000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f01ffc07000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f01ff8fe000)
/lib64/ld-linux-x86-64.so.2 (0x00007f02010fe000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f01ff6fa000)

运行:

./cpp-server

C++客户端

gen-cpp 上层新建 client.cpp:

// system
#include <iostream> // lib
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <boost/shared_ptr.hpp>
using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using boost::shared_ptr; // project
#include "gen-cpp/timeServe.h" int main() {
std::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
std::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); timeServeClient client(protocol); // open connect
transport->open();
auto timeNow = client.getCurrtentTime();
std::cout << timeNow << std::endl;
transport->close();
return 0;
}

对它进行编译:

g++ -std=c++11 -o cpp-client client.cpp gen-cpp/timeServe.cpp  -lthrift

运行:

./cpp-client
1553223392

Golang服务端

修改 timeRPC.thrift:

service timeServe {
i32 getCurrtentTime()
} service time2Serve {
i32 getCurrtentTime()
}

查看:

go env

GOPATH="/opt/gocode"

其中 $GOPATH/opt/gocode

准备必要库:

mkdir -p $GOPATH/src/github.com/apache
cd $GOPATH/src/github.com/apache
git clone https://github.com/apache/thrift.git

执行:

thrift --gen go timeRPC.thrift

在当前目录下生成一个叫做 "gen-go" 的文件夹,里面包含了需要的代码。

└── timerpc
├── GoUnusedProtection__.go
├── timeRPC-consts.go
├── timeRPC.go
└── time_serve-remote
└── time_serve-remote.go

gen-go 上层新建 server.go:

package main

import (
"context"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
"net"
"os"
"thrift_example/gen-go/timerpc"
"time"
) type MyTime struct{} func (s *MyTime) GetCurrtentTime(_ context.Context) (r int32, err error) {
t := int32(time.Now().Unix())
fmt.Printf("come on:%d\n", t)
return t, nil
} type MyTime2 struct{} func (s *MyTime2) GetCurrtentTime(_ context.Context) (r int32, err error) {
t := int32(time.Now().Unix())
fmt.Printf("come on2:%d\n", t)
return t, nil
} func main() {
// 创建服务器
serverTransport, err := thrift.NewTServerSocket(net.JoinHostPort("127.0.0.1", "9090"))
if err != nil {
fmt.Println("Error!", err)
os.Exit(1)
} // 创建二进制协议
protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory()) // 创建Processor,用一个端口处理多个服务
multiProcessor := thrift.NewTMultiplexedProcessor()
MyTimeProcessor := timerpc.NewTimeServeProcessor(new(MyTime))
MyTime2Processor := timerpc.NewTimeServeProcessor(new(MyTime2)) // 给每个service起一个名字
multiProcessor.RegisterProcessor("mytime", MyTimeProcessor)
multiProcessor.RegisterProcessor("mytime2", MyTime2Processor) server := thrift.NewTSimpleServer4(multiProcessor, serverTransport, transportFactory, protocolFactory) fmt.Println("start")
if err := server.Serve(); err != nil {
panic(err)
} // 退出时停止服务器
defer server.Stop()
}

编译并运行:

go build server.go
./server

Golang客户端

gen-go 上层新建 client.go:

package main

import (
"context"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
"net"
"os"
"thrift_example/gen-go/timerpc"
) func main() {
// 先建立和服务器的连接的socket,再通过socket建立Transport
socket, err := thrift.NewTSocket(net.JoinHostPort("127.0.0.1", "9090"))
if err != nil {
fmt.Println("Error opening socket:", err)
os.Exit(1)
}
transport := thrift.NewTFramedTransport(socket) // 创建二进制协议
protocol := thrift.NewTBinaryProtocolTransport(transport) // 打开Transport,与服务器进行连接
if err := transport.Open(); err != nil {
fmt.Fprintln(os.Stderr, "Error opening socket to "+"localhost"+":"+"9090", err)
os.Exit(1)
}
defer transport.Close() // 接口需要context,以便在长操作时用户可以取消RPC调用
ctx := context.Background() // 使用Mytime服务
MyTimeProtocol := thrift.NewTMultiplexedProtocol(protocol, "mytime") // 创建代理客户端,使用TMultiplexedProtocol访问对应的服务
c := thrift.NewTStandardClient(MyTimeProtocol, MyTimeProtocol) client := timerpc.NewTimeServeClient(c)
res, err := client.GetCurrtentTime(ctx)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(res) // 使用其他服务
// 步骤与上面的相同
// 使用Mytime服务
MyTime2Protocol := thrift.NewTMultiplexedProtocol(protocol, "mytime2")
c2 := thrift.NewTStandardClient(MyTime2Protocol, MyTime2Protocol)
client2 := timerpc.NewTimeServeClient(c2)
res, err = client2.GetCurrtentTime(ctx)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(res)
}

编译并运行:

go build client.go
./client

转载请注明:http://www.lenggirl.com/cap/thrift.html

Thrift RPC Golang、C++ Example的更多相关文章

  1. Golang、Php、Python、Java基于Thrift0.9.1实现跨语言调用

    目录: 一.什么是Thrift? 1) Thrift内部框架一瞥 2) 支持的数据传输格式.数据传输方式和服务模型 3) Thrift IDL 二.Thrift的官方网站在哪里? 三.在哪里下载?需要 ...

  2. thrift rpc通信

    thrift rpc通信 框架 别人的简历: 负责抓取程序的开发和维护,对抓取内容进行数据提取.整理.1.定向数据抓取程序的维护和开发,了解了Sqlite数据库.Thrift服务和多线程的开发调试.2 ...

  3. thrift 的required、optional探究

    原因 经常使用thrift来编写rpc通信,但是对下面两个问题还是有些疑惑 thrift 的required.optional和不写有什么区别 optional不设置isset的话被传输后值? 实验 ...

  4. 转载-- http接口、api接口、RPC接口、RMI、webservice、Restful等概念

     http接口.api接口.RPC接口.RMI.webservice.Restful等概念 收藏 Linux一叶 https://my.oschina.net/heavenly/blog/499661 ...

  5. ubuntu下使用golang、qml与ubuntu sdk开发桌面应用

    ubuntu下使用golang.qml与ubuntu sdk开发桌面应用 (简单示例) 找了很长时间go的gui库,试了gtk,准备试qt的时候发现了这个qml库,试了下很好用. 准备工作 1.Go ...

  6. 2017年的golang、python、php、c++、c、java、Nodejs性能对比(golang python php c++ java Nodejs Performance)

    2017年的golang.python.php.c++.c.java.Nodejs性能对比 本人在PHP/C++/Go/Py时,突发奇想,想把最近主流的编程语言性能作个简单的比较, 至于怎么比,还是不 ...

  7. 2017年的golang、python、php、c++、c、java、Nodejs性能对比[续]

    2017年的golang.python.php.c++.c.java.Nodejs性能对比[续] 最近忙,这个话题放了几天,今天来个续集.   上篇传送门: 2017年的golang.python.p ...

  8. thrift RPC 框架的自我搭建

    安装thrift rpc   安装的系统是Centos 7 未成功的方法 :(原因没找到,但是还是要记录下) 安装依赖库 yum install automake libtool flex bison ...

  9. Thrift RPC实战(三) thrift序列化揭秘

    本文主要讲解Thrift的序列化机制, 看看thrift作为数据交换格式是如何工作的? 1.构造应用场景: 1). 首先我们先来定义下thrift的简单结构. 1 2 3 4 5 namespace ...

随机推荐

  1. 论文翻译 DOTA:A Large-scale Dataset for Object Detection in Aerial Images

      简介:武大遥感国重实验室-夏桂松和华科电信学院-白翔等合作做的一个航拍图像数据集 摘要: 目标检测是计算机视觉领域一个重要且有挑战性的问题.虽然过去的十几年中目标检测在自然场景已经有了较重要的成就 ...

  2. sppNet论文学习

    Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition 深度神经网络中用于视觉识别的空间金字塔池化 ...

  3. Spring声明式事务如何选择代理方式?

    Spring声明式事务如何选择代理方式   解决方法: 1.基于注解方法: <tx:annotation-driven transaction-manager="txManager&q ...

  4. Spring Cloud(7.1):安装Kafka和Redis

    Kafka安装 (1)从官方(http://kafka.apache.org/downloads)下载安装包.kafka安装包和一般安装包的命名方式不一样,我们看一个kafka包命名:kafka_2. ...

  5. 【Leetcode_easy】830. Positions of Large Groups

    problem 830. Positions of Large Groups solution1: class Solution { public: vector<vector<int&g ...

  6. jsPlumb 基本概念

    jsPlumb 基本概念 一.默认属性 Anchor:锚点(连接点位置),可以设置在任何没有锚点的目标上(endPoint) Anchors:设置在connect的源和目标点的连接点位置,默认是 Bo ...

  7. MG7780打印机喷嘴堵塞

    1.深度清洗,打印喷嘴图案,发现有颜色没有打印出来 2.墨盒一加墨水就往外冒,以为是满的,其实是内部已经堵塞而加不进去,因为出墨口并没有墨水向外流(出墨口没有盖起来).解决办法就是用没有针头的针管从加 ...

  8. (CVE-2017-7269 ) IIS6.0实现远程控制

    简介 IIS 6.0默认不开启WebDAV,一旦开启了WebDAV,安装了IIS6.0的服务器将可能受到该漏洞的威胁 利用条件 Windows 2003 R2开启WebDAV服务的IIS6.0 环境搭 ...

  9. IO流学习

    1,流是一组有顺序的,有起点和重点的字节集合,是对数据传输的总称和抽象.即数据在两个设备之间的传输称作流.流的本质就是数据传输,根据数据传输的特性,将流抽象为各种累,方便直观的进行数据操作. 2,根据 ...

  10. 最新 乐游网络java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.乐游网络等10家互联网公司的校招Offer,因为某些自身原因最终选择了乐游网络.6.7月主要是做系统复习.项目复盘.Leet ...