前面介绍过 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. java普通项目打包成可执行jar文件时如何添加第三包

    在java的web项目中,引用第三方包的时候非常简单.因为在web项目上中,默认有一个web-inf文件夹.web-inf文件夹下有一个lib文件夹,如果有用到第三方包,直接丢进去就行了.但是对于普通 ...

  2. Java学习笔记之基础语法(顺序,条件,循环语句)

    顺序结构:自上而下 条件分支选择结构: if条件语句   1,一旦某一个分支确定执行以后,其他分支就不会执行.if后面的条件必须是boolean类型   2,if  后面如果不加大括号,默认相邻的下一 ...

  3. JavaScript专题之事件循环

    准备知识 1. 进程(process) 进程是系统资源分配一个独立单位,一个程序至少有一个进程.比方说:一个工厂代表一个 CPU, 一个车间就是一个进程,任一时刻,只能有一个进程在运行,其他进程处于非 ...

  4. [BZOJ2724] 蒲公英

    题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了.我觉得把那么可怕 ...

  5. ‎Cocos2d-x 学习笔记(20) ControlButton

    [Cocos2d-x 学习笔记 目录链接] 1. 简介 ControlButton实现了按钮功能,根据触摸的位置和移动的过程可识别9中EventType类型,执行对应的回调函数. 直接继承了Contr ...

  6. Shiro learning - 入门学习 Shiro中的基础知识(1)

    Shiro入门学习 一 .什么是Shiro? 看一下官网对于 what is Shiro ? 的解释 Apache Shiro (pronounced “shee-roh”, the Japanese ...

  7. Mysql UTF-8mb4字符集的问题

    官方Mysql手册链接 https://dev.mysql.com/doc/connectors/en/connector-j-reference-charsets.html Notes For Co ...

  8. Linux上安装mysql,实现主从复制

    MYSQL(mariadb) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可.开发这个分支的原因之一是:甲骨文公司收购了MySQL后,有将MySQL闭源的 ...

  9. jwt token

    1 ,session 认证机制: ,用户登录,传递用户名和密码给客户端 ,服务器进行用户名和密码的校验,如果校验成功,将用户保存到session ,将sessionid通过cookie返回给客服端,客 ...

  10. 在ASP.NET Core中编写合格的中间件

    这篇文章探讨了让不同的请求去使用不同的中间件,那么我们应该如何配置ASP.NET Core中间件?其实中间件只是在ASP.NET Core中处理Web请求的管道.所有ASP.NET Core应用程序至 ...