我们来看一下服务端的简单实现,直接上thrift代码,很直观的来看一看thrift的server到底干了些什么

  public boolean process(TProtocol in, TProtocol out) throws TException {
TMessage msg = in.readMessageBegin();
ProcessFunction fn = (ProcessFunction)this.processMap.get(msg.name);
if (fn == null) {
TProtocolUtil.skip(in, (byte)12);
in.readMessageEnd();
TApplicationException x = new TApplicationException(1, "Invalid method name: '" + msg.name + "'");
out.writeMessageBegin(new TMessage(msg.name, (byte)3, msg.seqid));
x.write(out);
out.writeMessageEnd();
out.getTransport().flush();
return true;
} else {
fn.process(msg.seqid, in, out, this.iface);
return true;
}
}
TMessage msg = in.readMessageBegin();这段代码的意思是从client端获取到二进制数据时候,获取Tmessage实例,和client的wirteMessage方法进行对应,聪明的小伙伴这个时候一定会想到这个是怎么解析的
为什么没有解析消息体长度和消息体内容的部分代码,不要着急我们一步一步渗透,readMessageBegin核心代码如下
  public TMessage readMessageBegin() throws TException {
int size = this.readI32();
if (size < 0) {
int version = size & -65536;
if (version != -2147418112) {
throw new TProtocolException(4, "Bad version in readMessageBegin");
} else {
return new TMessage(this.readString(), (byte)(size & 255), this.readI32());
}
} else if (this.strictRead_) {
throw new TProtocolException(4, "Missing version in readMessageBegin, old client?");
} else {
return new TMessage(this.readStringBody(size), this.readByte(), this.readI32());
}
}
int size = this.readI32();是做了些什么,接着往下看
 public int readI32() throws TException {
byte[] buf = this.i32rd;
int off = 0;
if (this.trans_.getBytesRemainingInBuffer() >= 4) {
buf = this.trans_.getBuffer();
off = this.trans_.getBufferPosition();
this.trans_.consumeBuffer(4);
} else {
this.readAll(this.i32rd, 0, 4);
} return (buf[off] & 255) << 24 | (buf[off + 1] & 255) << 16 | (buf[off + 2] & 255) << 8 | buf[off + 3] & 255;
}

这个地方代码就很清晰了,原来是从trans里面或取得字节流数据。

 private int readAll(byte[] buf, int off, int len) throws TException {
this.checkReadLength(len);
return this.trans_.readAll(buf, off, len);
}

继续能翻到最终的代码解析部分

private void readFrame() throws TTransportException {
this.transport_.readAll(this.i32buf, 0, 4);
int size = decodeFrameSize(this.i32buf);
if (size < 0) {
throw new TTransportException("Read a negative frame size (" + size + ")!");
} else if (size > this.maxLength_) {
throw new TTransportException("Frame size (" + size + ") larger than max length (" + this.maxLength_ + ")!");
} else {
byte[] buff = new byte[size];
this.transport_.readAll(buff, 0, size);
this.readBuffer_.reset(buff);
}
}

这里就很明显了,首先read一个四个字节的长度,这个int类型代表着后面要跟着接收的消息体的长度,来源是client的发送内容,然后在根据消息体长度在读出来所有的内容,然后缓存到readBuffer_中,然后再读取内容的时候直接从readBuffer_中获取字节流就可以了。

好了,服务端接收二进制数据解析的关键点就在这里了,接下来开始,我将用大量的篇幅开始讲解我的企业级RPC框架,满满的干货,感兴趣的小伙伴去我码云给个star吧!!!

https://gitee.com/a1234567891/koalas-rpc

koalas-RPC 个人作品,提供大家交流学习,有意见请私信,欢迎拍砖。客户端采用thrift协议,服务端支持netty和thrift的TThreadedSelectorServer半同步半异步线程模型,支持动态扩容,服务上下线,权重动态,可用性配置,页面流量统计等,持续为个人以及中小型公司提供可靠的RPC框架技术方案

更多学习内容请加高级java QQ群:825199617

 
												

JAVA RPC (六) 之thrift反序列化RPC消息体的更多相关文章

  1. JAVA RPC (五) 之thrift序列化RPC消息体

    让大家久等了.继续更新thrift序列化的消息体,下面我们一步一步的看一看thrift的rpc是怎么实例化消息体的. 首先我们先准备一个request文件 namespace java bky str ...

  2. thrift 是rpc协议

    PC(Remote Procedure Call,远程过程调用)是建立在Socket之上的,出于一种类比的愿望,在一台机器上运行的主程序,可以调用另一台机器上准备好的子程序,就像LPC(本地过程调用) ...

  3. RPC简介与Thrift框架

    RPC,全称是remote process call,远程过程调用,简单来讲就是调用部署在另一台服务器上的服务或者被部署在另一台服务器上的服务调用.由于各服务部署在不同机器,服务间的调用免不了网络通信 ...

  4. 开源RPC(gRPC/Thrift)框架性能评测

    海量互联网业务系统只能依赖分布式架构来解决,而分布式开发的基石则是RPC:本文主要针对两个开源的RPC框架(gRPC. Apache Thrift),以及配合GoLang.C++两个开发语言进行性能对 ...

  5. JAVA RPC 生产级高可用RPC框架使用分享

    先放出链接,喜欢的给个star:https://gitee.com/a1234567891/koalas-rpc 一:项目介绍 koalas-RPC 个人作品,提供大家交流学习,有意见请私信,欢迎拍砖 ...

  6. Thrift RPC实战(三) thrift序列化揭秘

    本文主要讲解Thrift的序列化机制, 看看thrift作为数据交换格式是如何工作的? 1.构造应用场景: 1). 首先我们先来定义下thrift的简单结构. 1 2 3 4 5 namespace ...

  7. rpc框架之 thrift连接池实现

    接前一篇rpc框架之HA/负载均衡构架设计 继续,写了一个简单的thrift 连接池: 先做点准备工作: package yjmyzz; public class ServerInfo { publi ...

  8. C#使用Thrift作为RPC框架入门(三)之三层架构

    前言 这是我们讲解Thrift框架的第三篇文章,前两篇我们讲了Thrift作为RPC框架的基本用法以及架构的设计.为了我们更好的使用和理解Thrift框架,接下来,我们将来学习一下Thrift框架提供 ...

  9. Thrift写RPC接口

    Thrift总结(二)创建RPC服务 前面介绍了thrift 基础的东西,怎么写thrift 语法规范编写脚本,如何生成相关的语言的接口.不清楚的可以看这个<Thrift总结(一)介绍>. ...

随机推荐

  1. Python不能用于大型项目?关于Python的10大误解

     语言多元化是PayPal编程文化中一个重要的组成部分.在C++和Java长期流行的同时,更多的团队选择了Jva和Scala.同时,Braintree的收购也引入了一个久经世故的Ruby社区.Pyt ...

  2. NBIOT经典回答【转】

    转自:https://blog.csdn.net/pan0755/article/details/70145936 该部分分享的是物联网各垂直应用领域里,NB-IoT技术的部署,看看适合NB-IoT技 ...

  3. 【转】解决keepalived正常启动但是虚IP(VIP)没有生成的问题

    如题所示,keepalived安装配置好之后能够正常启动,但是虚IP并没有生成.接着检查防火墙(iptables)发现也没有相关的限制.稍微郁闷了一下之后,查看了keepalived日志文件,这次成功 ...

  4. python学习第22天

    封装 properpty classmathod staticmathod

  5. 【原创】大数据基础之Ambari(2)通过Ambari部署ElasticSearch(ELK)

    ambari2.7.3(hdp3.1) 安装 elasticsearch6.3.2 ambari的hdp中原生不支持elasticsearch安装,下面介绍如何通过mpack方式使ambari支持el ...

  6. 【python3接口自动化基础】json总结

    Json知识归纳: Post请求有两种方法传json参数 传json参数(自动转json了)---json=dict 传data参数(需json转换) ---data=json.dumps(dic) ...

  7. Python中的 @staticmethod@classmethod方法

    python类中有三种方法,常见的是实例方法,另外两种是staticmethod装饰的静态方法,和classmethod装饰的类方法. 1.对比 流畅的python里,用一个例子进行了对比: (1)两 ...

  8. javascript/jquery获取url地址栏参数的方法

    简洁jq方法获取url地址栏的参数 function getQueryVariable(variable){ var query = window.location.search.substring( ...

  9. How to fetch all Git branches

    问题描述 I cloned a Git repository, which contains about five branches. However, when I do git branch I ...

  10. Python 中文(大写)数字转阿拉伯数字(转)

    # constants for chinese_to_arabic CN_NUM = { '〇' : 0, '一' : 1, '二' : 2, '三' : 3, '四' : 4, '五' : 5, ' ...