go通过thrift连接hbase_Thrift总结(四)如何实现服务端与客户端的双向通信

前面介绍过 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(1: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 TransportCollection = new List();        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方法可将消息发送至服务端。

五、测试

测试效果如下:

582553f3f865dc8a1d2d24781add7bcc.png

六、最后

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值