我们来看一下服务端的简单实现,直接上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. spring事务源码分析结合mybatis源码(三)

    下面将结合mybatis源码来分析下,这种持久化框架是如何对connection使用,来达到spring事务的控制. 想要在把mybatis跟spring整合都需要这样一个jar包:mybatis-s ...

  2. 第八节,Opencv的基本使用------存取图像、视频功能、简单信息标注工具

    1.存取图像 import cv2 img=cv2.imread('test.jpg') cv2.imwrite('test1.jpg',img) 2.图像的仿射变换 图像的仿射变换涉及图像的形状位置 ...

  3. (转)Vue种key的作用

    https://blog.csdn.net/qq_41861679/article/details/80659278 https://cn.vuejs.org/v2/api/#key 其实不只是vue ...

  4. JVM·垃圾收集器与内存分配策略之垃圾回收算法!

    1.垃圾回收算法    1.1.标记-清除算法(Mark-Sweep):             过程分为“标记”和“清除”两个过程.先将所有需要回收的目标统一标记,然后再统一清除.          ...

  5. 如何查询oracle数据库中的各种角色

    1. 查询oracle中所有用户信息select * from dba_users;2. 只查询用户和密码select username,password from dba_users;3. 查询当前 ...

  6. select获取选中的option(包含value和text,重点是text怎么获取)

    简单描述:后台需要获取到select标签选择的内容,也就是text,该怎么取呢?很简单. 代码: //hml代码<div class="col-md-6"> <l ...

  7. svn忽略不需要同步的文件夹或文件

    如果某个文件已经提交到了svn,这个时候需要通过svn来把服务器上的改文件删除,然后再在本地,点击该文件 选择把该文件删除,recursively表示递归删除(文件下->下级文件夹->下级 ...

  8. Java判断水仙花数

    水仙花数 水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI).自恋数.自幂数.阿姆斯壮数或阿姆斯特朗数( ...

  9. php判断浏览器还是微信打开

    本人亲测,但是存在一个小问题,就是用此方法在手机端打开会显示Google Chrome,但是在PC端是没有问题的,现在还在测试,先把第一版代码分享给大家! if(strpos($_SERVER['HT ...

  10. jQuery的下拉选select2插件用法

    1转自:https://www.jb51.net/article/95561.htm 用了这么久的Select2插件,也该写篇文章总结总结.当初感觉Select2不是特别好用,但又找不到比它更好的下拉 ...