讲述一下如何使用Thrift搭建C#版的客户端以及服务端通讯的程序
1. 先从官网下载Thrift安装包以及签出SVN源码:
官网下载地址:http://thrift.apache.org/download/
这里我下载了一个Thrift compiler for Windows版本的EXE文件(thrift-0.7.0.exe)
签出SVN源码地址:http://svn.apache.org/repos/asf/thrift/trunk
2. 首先创建脚本,命名为textCsharp.thrift,脚本内容如下:
namespace java com.javabloger.gen.code # 注释1 namespace csharp com.javabloger.gen.code # 注释1 namespace cpp com.javabloger.gen.code namespace perl com.javabloger.gen.code namespace php com.javabloger.gen.code struct Blog { # 注释2 1: string topic 2: binary content 3: i64 createdTime 4: string id 5: string ipAddress 6: map<string,string> props } service ThriftCase { # 注释3 i32 testCase1(1:i32 num1, 2:i32 num2, 3:string num3) # 注释4 list<string> testCase2(1:map<string,string> num1) void testCase3() void testCase4(1:list<Blog> blog) }
类型 描述
bool true, false
byte 8位的有符号整数
i16 16位的有符号整数
i32 32位的有符号整数
i64 64位的有符号整数
double 64位的浮点数
string UTF-8编码的字符串
binary 字符数组
struct 结构体
list 有序的元素列表,类似于STL的vector
set 无序的不重复元素集,类似于STL的set
map key-value型的映射,类似于STL的map
exception 是一个继承于本地语言的exception基类
service 服务。包含多个函数接口(纯虚函数)
bool true, false
byte 8位的有符号整数
i16 16位的有符号整数
i32 32位的有符号整数
i64 64位的有符号整数
double 64位的浮点数
string UTF-8编码的字符串
binary 字符数组
struct 结构体
list 有序的元素列表,类似于STL的vector
set 无序的不重复元素集,类似于STL的set
map key-value型的映射,类似于STL的map
exception 是一个继承于本地语言的exception基类
service 服务。包含多个函数接口(纯虚函数)
3. 执行thrift命令:thrift -gen csharp testCsharp.thrift,这里说明一下:参数"csharp”意味着这里将自动生成C#代码,如果这里写java,python等等,可以用"java"或者"py”代替。
thrift-0.7.0.exe -r -gen java TestThrift.thrift 生成java 代码
thrift-0.7.0.exe -r -gen php TestThrift.thrift 生成php代码
thrift-0.7.0.exe -r -gen py TestThrift.thrift 生成python代码
thrift-0.7.0.exe -r -gen as3 TestThrift.thrift 生成as3代码
thrift-0.7.0.exe -r -gen cpp TestThrift.thrift 生成C++代码
thrift-0.7.0.exe -r -gen php TestThrift.thrift 生成php代码
thrift-0.7.0.exe -r -gen py TestThrift.thrift 生成python代码
thrift-0.7.0.exe -r -gen as3 TestThrift.thrift 生成as3代码
thrift-0.7.0.exe -r -gen cpp TestThrift.thrift 生成C++代码
于是得到gen-csharp的目录,这个目录里面就包含支持Thrift的Blog以及ThriftCase的源代码,具体里面都生成什么代码,后面会做出介绍。
4.然后,我现在打开SVN源码中的 trunk\lib\csharp\ 路径,我用项目打开,编译后,得到Thrift.dll文件,为了后面使用Thrift做准备。
5.新建工程,添加Server以及Client项目,把刚才生成的代码文件放入Common项目中。让Client和Server项目引用Thrift.dll类库。
6.编写服务端程序:
public class Server { public void Start() { TServerSocket serverTransport = new TServerSocket(7911, 0, false); ThriftCase.Processor processor = new ThriftCase.Processor(new BusinessImpl()); TServer server = new TSimpleServer(processor, serverTransport); Console.WriteLine("Starting server on port 7911 ..."); server.Serve(); } }
其中BusinessImpl具体提供业务逻辑的实现:
public class BusinessImpl : ThriftCase.Iface { public int testCase1(int num1, int num2, String num3) { int i = num1 + num2; Console.Write( "testCase1 num1+num2 is :"+ i); Console.WriteLine( " num3 is :"+ num3); return i; } public List<String> testCase2(Dictionary<String, String> num1) { Console.WriteLine("testCase2 num1 :" + num1); List<String> list = new List<String>(); list.Add("num1"); return list; } public void testCase3() { Console.WriteLine("testCase3 ..........." + DateTime.Now); } public void testCase4(List<Blog> blogs) { Console.WriteLine("testCase4 ..........."); for (int i = 0; i < blogs.Count; i++) { Blog blog = blogs[i]; Console.Write("id:" + blog.Id); Console.Write(",IpAddress:" + blog.IpAddress); //Console.Write (",Content:" + new String(blog.Content)); Console.Write(",topic:" + blog.Topic); Console.Write(",time:" + blog.CreatedTime); } Console.WriteLine("\n"); } }
7. 编写客户端程序:
class Client { static Dictionary<String, String> map = new Dictionary<String, String>(); static List<Blog> blogs = new List<Blog>(); static void Main(string[] args) { TTransport transport = new TSocket("localhost", 7911); TProtocol protocol = new TBinaryProtocol(transport); ThriftCase.Client client = new ThriftCase.Client(protocol); transport.Open(); Console.WriteLine("Client calls ....."); map.Add("blog", "http://www.javabloger.com%22);/ client.testCase1(10, 21, "3"); client.testCase2(map); client.testCase3(); Blog blog = new Blog(); //blog.setContent("this is blog content".getBytes()); blog.CreatedTime = DateTime.Now.Ticks; blog.Id = "123456"; blog.IpAddress = "127.0.0.1"; blog.Topic = "this is blog topic"; blogs.Add(blog); client.testCase4(blogs); transport.Close(); Console.ReadKey(); } }
8.先运行Server在运行Client。
9.补充java实现
创建服务
1创建user.thrift
定义了一个User ,一个UerNotFound异常,一个UserService服务接口
注意定义的时候 序号是不可省略的,使用序号可以提升序列化和反序列对象的速度。
2.生成代码
生成java代码:thrift-0.6.1.exe --gen java user.thrift
3.实现服务端
3.1接口服务实现
3.2 Server启动类
4.实现客户端
创建服务
1创建user.thrift
namespace java thrift.demo.gen namespace py thrift.demo struct User{ 1: i32 id, 2: string username, 3: string password } exception UserNotFound{ 1:string message } service UserService{ list<User> getUsers(), User getUserByName(1:string username) throws(1:UserNotFound unf) }
定义了一个User ,一个UerNotFound异常,一个UserService服务接口
注意定义的时候 序号是不可省略的,使用序号可以提升序列化和反序列对象的速度。
2.生成代码
生成java代码:thrift-0.6.1.exe --gen java user.thrift
3.实现服务端
3.1接口服务实现
package thrift.demo.server; import java.util.ArrayList; import java.util.List; import org.apache.thrift.TException; import thrift.demo.gen.User; import thrift.demo.gen.UserNotFound; import thrift.demo.gen.UserService.Iface; public class UserServiceHandler implements Iface { @Override public List<User> getUsers() throws TException { List<User> list = new ArrayList<User>(); User user = new User(); user.setId(1); user.setUsername("user1"); user.setPassword("pwd1"); list.add(user); User user2 = new User(); user2.setId(1); user2.setUsername("user2"); user2.setPassword("pwd2"); list.add(user2); return list; } @Override public User getUserByName(String username) throws UserNotFound, TException { if ("user1".equals(username)) { User user = new User(); user.setId(1); user.setUsername("user1"); user.setPassword("pwd1"); return user; } else { throw new UserNotFound(); } } }
3.2 Server启动类
package thrift.demo.server; import org.apache.thrift.TProcessorFactory; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.server.THsHaServer; import org.apache.thrift.server.TServer; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TTransportException; import thrift.demo.gen.UserService; public class UserServer { public final static int PORT = 8989; /** * @param args */ public static void main(String[] args) { try { TNonblockingServerSocket socket = new TNonblockingServerSocket(PORT); final UserService.Processor processor = new UserService.Processor( new UserServiceHandler()); THsHaServer.Args arg = new THsHaServer.Args(socket); arg.protocolFactory(new TCompactProtocol.Factory()); arg.transportFactory(new TFramedTransport.Factory()); arg.processorFactory(new TProcessorFactory(processor)); TServer server = new THsHaServer(arg); server.serve(); } catch (TTransportException e) { e.printStackTrace(); } } }
4.实现客户端
package thrift.demo.client; import org.apache.thrift.TApplicationException; import org.apache.thrift.TException; import org.apache.thrift.protocol.TCompactProtocol; 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; import thrift.demo.gen.UserNotFound; import thrift.demo.gen.UserService; public class UserClient { public static void main(String[] arsg) { String address = "127.0.0.1"; int port = 8989; int clientTimeout = 30000; TTransport transport = new TFramedTransport(new TSocket(address, port, clientTimeout)); TProtocol protocol = new TCompactProtocol(transport); UserService.Client client = new UserService.Client(protocol); try { transport.open(); System.out.println(client.getUserByName("user1")); } catch (TApplicationException e) { System.out.println(e.getMessage() + " " + e.getType()); } catch (TTransportException e) { e.printStackTrace(); } catch (UserNotFound e) { e.printStackTrace(); } catch (TException e) { e.printStackTrace(); } transport.close(); } }
10.Thrift允许你选择 protocol ,transport和server。因为Thrift 最早是有C++开发的,Thrift在C++实现中有最大的变化。
Thrift支持 text 和 binary protocols,binary protocols要比text protocols,但是有时候 text protocols比较有用(例如:调试的时候)。支持的协议有:
TBinaryProtocol -直接的二进制格式
TCompactProtocol 效率和高压缩编码数据
TDenseProtocoal 和TCompactProtocol相似,但是省略了meta信息,从哪里发送的,增加了receiver。还在实验中,java实现还不可用。
TJSONProtocoal 使用JSON
TSImpleJSONProtocoal 只写的protocol使用JSON。适合被脚本语言转化
TDebugProtocoal 使用人类可读的text 格式 帮助调试
上面的protocol 说明了 什么被传送,Thrift transports 说明了怎样传送。支持的transport:
TSocket 使用 blocking socket I/O
TFramedTransport 以帧的形式发送,每帧前面是一个长度。要求服务器来non-blocking server
TFileTransport 写到文件。没有包括在java实现中。
TMemoryTransport 使用内存 I/O 。java实现中在内部使用了ByteArrayOutputStream
TZlibTransport 压缩 使用zlib。在java实现中还不可用
最后,thrift 提供了servers:
TSimpleServer 单线程 server,使用标准的blocking IO。用于测试
TThreadPoolServer 多线程 使用标准的blocking IO
TNonblockingServer 多线程 使用 non-blocking IO (java实现中使用了NIO channels)。TFramedTransport必须使用在这个服务器。
一个server只允许定义一个接口服务。这样的话多个接口需要多个server。这样会带来资源的浪费。同意通过继承接口的方式。
Thrift支持 text 和 binary protocols,binary protocols要比text protocols,但是有时候 text protocols比较有用(例如:调试的时候)。支持的协议有:
TBinaryProtocol -直接的二进制格式
TCompactProtocol 效率和高压缩编码数据
TDenseProtocoal 和TCompactProtocol相似,但是省略了meta信息,从哪里发送的,增加了receiver。还在实验中,java实现还不可用。
TJSONProtocoal 使用JSON
TSImpleJSONProtocoal 只写的protocol使用JSON。适合被脚本语言转化
TDebugProtocoal 使用人类可读的text 格式 帮助调试
上面的protocol 说明了 什么被传送,Thrift transports 说明了怎样传送。支持的transport:
TSocket 使用 blocking socket I/O
TFramedTransport 以帧的形式发送,每帧前面是一个长度。要求服务器来non-blocking server
TFileTransport 写到文件。没有包括在java实现中。
TMemoryTransport 使用内存 I/O 。java实现中在内部使用了ByteArrayOutputStream
TZlibTransport 压缩 使用zlib。在java实现中还不可用
最后,thrift 提供了servers:
TSimpleServer 单线程 server,使用标准的blocking IO。用于测试
TThreadPoolServer 多线程 使用标准的blocking IO
TNonblockingServer 多线程 使用 non-blocking IO (java实现中使用了NIO channels)。TFramedTransport必须使用在这个服务器。
一个server只允许定义一个接口服务。这样的话多个接口需要多个server。这样会带来资源的浪费。同意通过继承接口的方式。
各个server的性能对比见文章 http://liyonghui160com.iteye.com/admin/blogs/2088945
相关推荐
Thrift初探:简单实现C#通讯服务程序
Thrift中实现Java与Python的RPC互相调用示例代码;Thrift中实现Java与Python的RPC互相调用示例代码;Thrift中实现Java与Python的RPC互相调用示例代码
Thrift0.9.1 示例代码 Java版本 Thrift0.9.1 示例代码 Java版本
thrift服务,java调用C#完整代码
Thrift双向通讯java代码
Thrift作为可伸缩的跨语言服务开发框架,网上的资源较少,这里是一个简单的入门小程序,文件中的mylib下包含了依赖的jar包,并且在file目录下放了一个简单的thrift文件和生成thrift-0.9.0.exe工具,直接使用 thrift-...
技术分享:Java通过Thrift框架实现通讯的示例代码
java代码使用thrift2操作hbase示例,thrift2连接hbase添加数据,单条查找,删除数据,根据扫描器查找,修改数据等测试实例
thrift在windows下生成C#代码
利用thrift实现js与C#通讯的实例代码,需要的朋友可以参考一下
Thrift Java 服务器 客户端通信,网上看到的,觉得不错就分享出来供大家一起共同分享学习。
本例改编自Apache Thrift教程: ... ... 原教程使用的是c++ server和php client. 我用c++和c#分别实现了client和server,他们之间可以用任意组合互相调用,没有太复杂的功能,非常利于初学Thrift.
基于Thrift的Golang与c#程序互相访问
thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Go,Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, ...
一个java和python的thrift例子,其中java作为服务端,python作为客户端
thrift java build jar
thrift 通讯 简单的 Thrift 实现实例,使读者能够快速直观地了解什么是 Thrift 以及如何使用 Thrift 构建服务。
thrift通过http实现的一个java例子!
主要是对thrift0.9.0 TSimpleServer、TThreadPoolServer 、TNonblockingServer、THsHaServer等服务模型实例和AsynClient 异步客户端实例代码的演示