JAVA RPC (六) 之thrift反序列化RPC消息体
我们来看一下服务端的简单实现,直接上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消息体的更多相关文章
- JAVA RPC (五) 之thrift序列化RPC消息体
让大家久等了.继续更新thrift序列化的消息体,下面我们一步一步的看一看thrift的rpc是怎么实例化消息体的. 首先我们先准备一个request文件 namespace java bky str ...
- thrift 是rpc协议
PC(Remote Procedure Call,远程过程调用)是建立在Socket之上的,出于一种类比的愿望,在一台机器上运行的主程序,可以调用另一台机器上准备好的子程序,就像LPC(本地过程调用) ...
- RPC简介与Thrift框架
RPC,全称是remote process call,远程过程调用,简单来讲就是调用部署在另一台服务器上的服务或者被部署在另一台服务器上的服务调用.由于各服务部署在不同机器,服务间的调用免不了网络通信 ...
- 开源RPC(gRPC/Thrift)框架性能评测
海量互联网业务系统只能依赖分布式架构来解决,而分布式开发的基石则是RPC:本文主要针对两个开源的RPC框架(gRPC. Apache Thrift),以及配合GoLang.C++两个开发语言进行性能对 ...
- JAVA RPC 生产级高可用RPC框架使用分享
先放出链接,喜欢的给个star:https://gitee.com/a1234567891/koalas-rpc 一:项目介绍 koalas-RPC 个人作品,提供大家交流学习,有意见请私信,欢迎拍砖 ...
- Thrift RPC实战(三) thrift序列化揭秘
本文主要讲解Thrift的序列化机制, 看看thrift作为数据交换格式是如何工作的? 1.构造应用场景: 1). 首先我们先来定义下thrift的简单结构. 1 2 3 4 5 namespace ...
- rpc框架之 thrift连接池实现
接前一篇rpc框架之HA/负载均衡构架设计 继续,写了一个简单的thrift 连接池: 先做点准备工作: package yjmyzz; public class ServerInfo { publi ...
- C#使用Thrift作为RPC框架入门(三)之三层架构
前言 这是我们讲解Thrift框架的第三篇文章,前两篇我们讲了Thrift作为RPC框架的基本用法以及架构的设计.为了我们更好的使用和理解Thrift框架,接下来,我们将来学习一下Thrift框架提供 ...
- Thrift写RPC接口
Thrift总结(二)创建RPC服务 前面介绍了thrift 基础的东西,怎么写thrift 语法规范编写脚本,如何生成相关的语言的接口.不清楚的可以看这个<Thrift总结(一)介绍>. ...
随机推荐
- windows下的node环境搭建
node环境的搭建过程: 1.首先在nodejs.org官网上下载一个msi安装文件,安装(过程很简单,基本上是一路next) 2.安装完成后,简单测试下是否安装成功,在cmd下输入两个命令: nod ...
- Spring Boot项目部署到外部Tomcat服务器
2017年04月27日 23:33:52 阅读数:7542 前言 Spring Boot项目一般都是内嵌tomcat或者jetty服务器运行,很少用war包部署到外部的服务容器,即使放到linux中, ...
- Python学习笔记四
一.装饰器 1.知识储备 函数对象 函数可以被引用 函数可以当参数传递 返回值可以是函数 可以当作容器的元素 def func1(): print (666) def func2(): print ( ...
- 洛谷P4482 [BJWC2018]Border 的四种求法 字符串,SAM,线段树合并,线段树,树链剖分,DSU on Tree
原文链接https://www.cnblogs.com/zhouzhendong/p/LuoguP4482.html 题意 给定一个字符串 S,有 q 次询问,每次给定两个数 L,R ,求 S[L.. ...
- WIN10在安装mysql时,出现“The security settings could not be applied to the database because the connection has failed with the following error. Error Nr. 1045
解决方法:1, 首先卸载MySQL2, 再根据这个目录 C:\ProgramData,将MySQL删除.3, 重新安装MySQL 就好了(电脑不用重启)
- 多台CentOS服务器下实现SSH免密码登录
ROOT用户下实现SSH免密码登录 第一步:进入目录/root/.ssh $ cd /root/.ssh/ 执行以下命令,会在当前目录下生成公钥(id_rsa.pub)/私钥(id_rsa)对 第二 ...
- python基础篇_006_面向对象
面向对象 1.初识类: # 定义一个函数,我们使用关键字 def """ def 函数名(参数): '''函数说明''' 函数体 return 返回值 "&qu ...
- SpringCloud使用Nacos服务发现实现远程调用
本文使用SpringCloud结合Nacos服务发现,Feign远程调用做一个简单的Demo. 1 Nacos 关于Nacos之前写了两篇文章关于SpringBoot对它的使用,感兴趣可以查看一下. ...
- gcc各个版本下载
http://www.gnu.org/order/ftp.html http://ftp.gnu.org/gnu/gcc/
- C++ 简单的控制台贪吃蛇小游戏
由于比较懒,所以不怎么写,觉得这样不应该.我应该对自己学的做出整理,不管是高端低端,写出来是自己的. // 贪吃蛇.cpp : 定义控制台应用程序的入口点. // #include "std ...