前面介绍过 Thrift 安装和使用,介绍了Thrift服务的发布和客户端调用,可以查看我之前的文章:https://www.cnblogs.com/zhangweizhong/category/1006119.html

但是,之前介绍的都是单向的客户端发送消息,服务端接收消息。而客户端却得不到服务器的响应。

那如果我们要实现双向通信(即:客户端发送请求,服务端处理返回,服务端发送消息,客户端处理返回)的功能,该怎么实现呢?

其实在不涉及语言平台的制约,WebService或是webapi 就可以实现这种客户端发起请求,服务端的处理的单向流程。

然而,实际场景中,可能我们的某些业务需求,更需要服务端能够响应请求并处理数据。下面我通过一个demo案例,介绍下Thrift 是如何实现双向通信的。

一、安装Thrift

这里不再赘述,戳这里查看我上篇文章的介绍:https://www.cnblogs.com/zhangweizhong/category/1006119.html

二、编写Thrift IDL文件

编写thrift脚本,命名为student.thrift  如下:

service HelloWorldService{
void SayHello(:string msg);
}

生成service 的方法,之前的文章有介绍,这里就不介绍了。

三、编写服务端代码

创建HelloThrift.Server 服务端工程,添加HelloWorldBidirectionServer类,HelloWorldBidirectionServer 实现了Iface接口用于接收客户端消息,并有一个客户端传输层对象集合用于记录所有已连接的客户端。

 public class HelloWorldBidirectionServer : HelloWorldBidirectionService.Iface
{
public void Run(int port)
{
try
{
TServerTransport transport = new TServerSocket(port); TTransportFactory transportFac = new TTransportFactory(); TProtocolFactory inputProtocolFactory = new TBinaryProtocol.Factory();
TThreadPoolServer server = new TThreadPoolServer(getProcessorFactory(), transport, transportFac, inputProtocolFactory); server.Serve();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
} public static List<TTransport> TransportCollection = new List<TTransport>(); public void SayHello(string msg)
{
Console.WriteLine(string.Format("{0:yyyy/MM/dd hh:mm:ss} 服务端接收到消息: {1}", DateTime.Now, msg));
} public void SayToClient(string msg)
{
try
{
foreach (TTransport trans in TransportCollection)
{
TBinaryProtocol protocol = new TBinaryProtocol(trans);
HelloWorldBidirectionService.Client client = new HelloWorldBidirectionService.Client(protocol);
//Thread.Sleep(1000);
client.SayHello(msg);
//Console.WriteLine("发给了客户端哟");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
} public TProcessorFactory getProcessorFactory()
{
return new HelloWorldBidirectionProcessor();
}
} public class HelloWorldBidirectionProcessor : TProcessorFactory
{
public TProcessor GetProcessor(TTransport trans, TServer server = null)
{
if (trans.IsOpen)
{
HelloWorldBidirectionServer.TransportCollection.Add(trans);
Console.WriteLine("客户端连上。");
} HelloWorldBidirectionServer srv = new HelloWorldBidirectionServer();
return new global::HelloWorldBidirectionService.Processor(srv);
}
}

四、编写客户端代码

首先创建HelloThrift.Client客户端项目,添加接收服务端消息的类HelloWorldBidirectionClient,里面只有一个实现Iface接口的方法:

  public class HelloWorldBidirectionClient
{
static HelloWorldBidirectionService.Client client = null;
public void ConnectAndListern(int port, string ip = "127.0.0.1")
{
//Tsocket: TCP/IP Socket接口
TSocket tSocket = new TSocket(ip, port);
//消息结构协议
TProtocol protocol = new TBinaryProtocol(tSocket);
try
{
if (client == null)
{
client = new global::HelloWorldBidirectionService.Client(protocol);
tSocket.Open();//建立连接
StartListern(tSocket);//启动监听线程
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
} public void Say(string msg)
{
if (client != null)
client.SayHello(msg);
} void StartListern(TSocket tSocket)
{
Thread t = new Thread(new ParameterizedThreadStart(Run));
t.Start(tSocket);
} public void Run(object tSocket)
{
HelloWorldBidirectionService.Processor process = new HelloWorldBidirectionService.Processor(new HelloWorldBidirectionFace()); try
{
while (process.Process(new TBinaryProtocol((TSocket)tSocket), new TBinaryProtocol((TSocket)tSocket)))
{
Console.WriteLine("消息接收完成,等下一波,阻塞中......");
}
}
catch (Exception ex)
{
Console.WriteLine("连接断开..." + ex.Message);
}
} }
class HelloWorldBidirectionFace : HelloWorldBidirectionService.Iface
{
public void SayHello(string msg)
{
Console.WriteLine(string.Format("{0:yyyy/MM/dd hh:mm:ss} 收到服务端响应消息 {1}", DateTime.Now, msg)); }
}

实现客户端,ConnectAndListern方法可以与服务端建立连接,并开启客户端端口监听来自服务端的信息。Say方法可将消息发送至服务端。

五、测试

测试效果如下:

六、最后

  1. 关于使用Thrift 构建我们自己的rpc 的方法,这里基本讲完了。其他的方法本文就不再演示了,调用起来都是一样。

  2. 后续会简单讨论一下Thrift 框架的通信原理。

  3. 源代码下载,Weiz.Thrift.Shuangxiang.rar

Thrift总结(四)Thrift实现双向通信的更多相关文章

  1. Thrift笔记(四)--Thrift client源码分析

    thrift文件 namespace java com.gxf.demo namespace py tutorial typedef i32 int // We can use typedef to ...

  2. Thrift架构~动态Thrift插件的注入

    先说AOP 说到注入,大家就会想起来IoC和AOP,确实如些,这一讲中,我们通过unity来实现对thrift插件的动态注入,事实上,这个功能在以后的项目中经常要用到,比如,你将一些功能分发到指定服务 ...

  3. Thrift入门初探--thrift安装及java入门实例

    什么是thrift? 简单来说,是Facebook公布的一款开源跨语言的RPC框架. 那么问题来了. 什么是RPC框架? RPC全称为Remote Procedure Call,意为远程过程调用. 假 ...

  4. IDEA集成的 Thrift 插件进行 thrift 编译

    IDEA集成的 Thrift 插件进行 thrift 编译 注意 1.thrift文件要放在source目录,才有compile选项 2.generator list的output path不用加包名 ...

  5. 【thrift】thrift入门初探--thrift安装及java入门实例

    转载:https://www.cnblogs.com/fingerboy/p/6424248.html 公司的一些平台服务框架底层封装了thrift提供服务,最近项目不是很紧,于是研究了一下,刚刚入门 ...

  6. 【Thrift一】Thrift安装部署

    Thrift安装部署 Thrift安装部署 下载源码包 安装g++ 解压Thrift安装包 安装boost开发工具 测试(python版) 下载源码包 wget http://apache.fayea ...

  7. [development][thrift] RPC框架 thrift

    一: wiki:https://zh.wikipedia.org/wiki/Thrift 二: 来自IBM的介绍:https://www.ibm.com/developerworks/cn/java/ ...

  8. Thrift笔记(五)--Thrift server源码分析

    从(四)server代码跟进 public static void simple(MultiplicationService.Processor processor) { try { TServerT ...

  9. Thrift 个人实战--Thrift 网络服务模型

    前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...

随机推荐

  1. [HDU2294] Pendant - 矩阵加速递推

    Pendant Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  2. Python eval() exec()

    eval(str) 函数:将字符串 str 当成有效的表达式来求值并返回计算结果常见作用:1,计算字符串中有效的表达式,并返回结果In [55]: eval('pow(10,2)') # 函数Out[ ...

  3. 【Labview入门】子VI的调用

    labview版本:Labview2015 Labview里面也可以向C语言等变成语言一样调用子程序,本文带你一步一步实现子VI的创建与调用. 第一步 写好程序 首先我们写个简单的加法程序: 我们的目 ...

  4. HDU 1532 Drainage Ditches(最大流 EK算法)

    题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1532 思路: 网络流最大流的入门题,直接套模板即可~ 注意坑点是:有重边!!读数据的时候要用“+=”替 ...

  5. java中多线程 - 多线程中的基本方法

    介绍一下线程中基本的方法使用 线程睡眠sleep() Thread.sleep(毫秒);我们可以通过sleep方法设置让线程睡眠.可以看到sleep是个静态方法 public static nativ ...

  6. 远程桌面连接(mstsc)

    目录 1. 序言 2. 准备工作 3. 内网远程连接(以mstsc的方式) 4. 问题---凭据不工作 5. 外网远程连接(mstsc) 6. 结语 更新时间:2019.09.10 1. 序言 有时候 ...

  7. Android Studio配置Socks5代理后Gradle运行不正常

    第一次在Mac上运行Android Studio,遇到了一系列问题,其中一个代理问题搞得我是不知所措,在此记录. 如果你遇到了如下图的问题,那么恭喜你你可能已经找到了解决方案也就是本文: 一般,我们为 ...

  8. SpringBoot的Banner

    一 官方文档介绍 1 自定义横幅 通过在 classpath 中添加banner.txt文件或将banner.location设置为此类文件的位置,可以更改启动时打印的横幅.如果文件具有异常编码,则可 ...

  9. POJ2431 优先队列+贪心 - biaobiao88

    以下代码可对结构体数组中的元素进行排序,也差不多算是一个小小的模板了吧 #include<iostream> #include<algorithm> using namespa ...

  10. SpringBoot系列之@Value和@ConfigurationProperties

    继上一篇博客SpringBoot系列之YAML配置用法之后,再写一篇@Value.@ConfigurationProperties的对比博客 这两个主键都是可以获取配置文件属性的,不过是有比较大的区别 ...