文档章节

JAVA RPC (六) 之thrift反序列化RPC消息体

o
 osc_gu9d45li
发布于 2019/04/07 13:10
字数 780
阅读 31
收藏 0

精选30+云产品,助力企业轻松上云!>>>

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

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

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

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

 

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

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

 












o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
从零开始实现RPC框架 - RPC原理及实现

最近被人问到RPC相关的东西~突然发现还是有很多原理没有清楚,所以要好好系统的学习一下RPC以及它的原理 先大致了解一下RPC的大概,原文:https://blog.csdn.net/top_code/article/details/...

osc_271igh42
2018/06/21
2
0
从无到有RPC框架 - RPC原理及实现(文末还有开源的优秀RPC框架)

RPC概述 RPC(Remote Procedure Call)即远程过程调用,允许一台计算机调用另一台计算机上的程序得到结果,而代码中不需要做额外的编程,就像在本地调用一样。 现在互联网应用的量级越来越大,...

kx33389
2019/07/18
23
0
从零开始实现RPC框架 - RPC原理及实现

RPC概述 RPC(Remote Procedure Call)即远程过程调用,允许一台计算机调用另一台计算机上的程序得到结果,而代码中不需要做额外的编程,就像在本地调用一样。 现在互联网应用的量级越来越大,...

明杰IT
06/28
3
0
分布式架构核心RPC原理

在应用的迭代演进过程中,随着系统访问量提高,业务复杂度提高,代码复杂度提高,应用逐渐从单体式架构向面向服务的分布式架构转变。RPC(Remote Procedure Call Protocol远程过程调用)是分...

osc_4s0ww36w
2018/03/23
4
0
从零开始实现RPC框架 - RPC原理及实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/t4i2b10X4c22nF6A/article/details/88653236

JAVA高级架构v
2019/03/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

LINUX_VERSION_CODE与KERNEL_VERSION

由于Linux版本的在不断更新,当设备驱动去兼容不同版本的内核时,需要知道当前使用的内核源码版本,以此来调用对应版本的内核API,这两个宏定义在文件 /usr/include/linux/version.h#defin...

osc_5g68egoj
16分钟前
16
0
JVM09-类加载过程

这一篇我们来学习一下JVM中的类加载过程。说到类的加载过程,我们需要先了解一下JVM中类的生命周期。在JVM中类的生命周期有七个阶段。分别是: 加载(Loading):加载是通过类加载器从不同的...

osc_zai0dt9q
17分钟前
17
0
###豪豪豪豪######2020 推荐系统技术演进趋势了解

读知乎文章《推荐系统技术演进趋势:从召回到排序再到重排》笔记: 《推荐系统技术演进趋势:从召回到排序再到重排》这篇文章主要说了下最近两年,推荐系统技术的一些比较明显的技术发展趋势...

osc_lhmderwy
18分钟前
9
0
SpringBoot入门实现RESTFUL API以及用Postman测试

Model @Data@Builderpublic class Article { private Long id; private String author; private String title; private String content; private Date createTime;}......

osc_7ludm6s2
19分钟前
4
0
Leetcode 83 删除排序链表中的重复元素-链表双指针

维护两个指针,第一个指针指向链表没有重复元素的最后一个位置,第二个指针向后扫描,直到末尾。严格来说,在C++中需要手动释放内存。但在算法题或者Java中不需要这么做。 class Solution {...

osc_n1x6m26g
20分钟前
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部