前面介绍过 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. 除法分块 luogu2261 (坑)

    除法分块 除法分块 是指使用分块计算的方法求S=∑i=1n⌊ki⌋S=\sum^{n}_{i=1}{\lfloor{\frac{k}{i}}\rfloor}S=i=1∑n​⌊ik​⌋的值. 举个例子. ...

  2. linux-pclint代码检测

    win10.ubuntu16.04, vs2017. 1.安装pc-lint到C盘. 2.将linux下的usr整个目录打包拷贝到win10某盘下. 3.获取lint检测linux c++ 代码的宏参 ...

  3. python里怎么查看数据类型

    python里怎么查看数据类型? python里可以通过type()函数来查看数据类型. Python 内置函数 Python 内置函数 Python type() 函数如果你只有第一个参数则返回对象 ...

  4. 1.Linux-CentOS7.6安装教程

    了解Linux Linux 就是一个操作系统,主要为企业提供支持与服务. 学习Linux需要具备什么基础?能看懂中文,能看懂简单的 English ​ 1.什么是Linux? Linux:和我们常见的 ...

  5. vue系列---理解Vue中的computed,watch,methods的区别及源码实现(六)

    _ 阅读目录 一. 理解Vue中的computed用法 二:computed 和 methods的区别? 三:Vue中的watch的用法 四:computed的基本原理及源码实现 回到顶部 一. 理解 ...

  6. 百万年薪python之路 -- 列表

    1.列表(list)-- list关键字 列表是python的基础数据类型之一,有顺序,可以切片方便取值,它是以[ ]括起来, 每个元素用' , '隔开而且可以存放各种数据类型(字符串,数字,布尔值, ...

  7. JVM学习记录1--JVM内存布局

    先上个图 这是根据<Java虚拟机规范(第二版)>所画的jvm内存模型. 程序计数器:程序计数器是用来记录当前线程方法执行顺序的,对应的就是我们编程中一行行代码的执行顺序,如分支,跳转,循 ...

  8. Core3.0的 安装与坑坑坑!!!

    Core3的 SDK下载地址是:https://dotnet.microsoft.com/download/dotnet-core/3.0  ! 不要下载preview8!!!,请先下载 previe ...

  9. MySQL开发篇(5)索引、视图、触发器、SQL中的安全问题、SQL Mode、

    一.索引 所有MySQL列类型都可以被索引,对相关列使用索引是提高SELECT操作性能的最佳途径.每种存储引擎(MyISAM.InnoDB.BDB.MEMORY等)对每个表至少支持16个索引,总索引长 ...

  10. 在SpringBoot中使用flyway进行数据库版本管理

    本文大纲 flyway是什么 能帮助我们解决什么问题 springboot环境下使用flyway flyway的工作原理 一.flyway是什么 Flyway是一个开源的数据库版本管理工具,并且极力主 ...