RocketMq通信协议格式及编解码 (源码分析)
一、RocketMq broker服务器与客户端的网络通信是基于netty4.x实现的,重点分析 RocketMq设计的通信协议及对应的编解码 开发。
public ByteBuffer encode() {// 1> header length sizeint length = 4; //表示用4个字节来存储头部长度// 2> header data lengthbyte[] headerData = this.buildHeader(); //报文头部的数据length += headerData.length; //加上头部报文的字节长度// 3> body data lengthif (this.body != null) {length += body.length; //如果报文体body有数据则加上报文体的字节长度}ByteBuffer result = ByteBuffer.allocate(4 + length); //分配一个 (4+length)这么大的字节缓冲区,这个缓冲区就用来存储上述协议格式的整个报文的数据//下面代码开始往缓冲区存放数据// lengthresult.putInt(length); //缓冲区的最开始的4个字节用来存储总的长度length// header lengthresult.putInt(headerData.length); //缓冲区接下来4个字节用来存储报文头部的长度// header dataresult.put(headerData); //缓冲区接下来存储报文头部数据// body data;if (this.body != null) {result.put(this.body); //缓冲区最后用来存储报文体的数据}result.flip(); //将缓冲区翻转,用于将ByteBuffer放到网络通道中进行传输return result;}
public class NettyDecoder extends LengthFieldBasedFrameDecoder {private static final Logger log = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);private static final int FRAME_MAX_LENGTH = //Integer.parseInt(System.getProperty("com.rocketmq.remoting.frameMaxLength", "8388608"));public NettyDecoder() {super(FRAME_MAX_LENGTH, 0, 4, 0, 4); //0,4,0,4 每一个0,4,这个是表示存放长度的变量的字节所占的长度,为4个,第二个4表示就是解码之后的数据包跳过的字节数为4,表示就将数据包的头部给去掉了。}//此处省略一万字
}
public static RemotingCommand decode(final ByteBuffer byteBuffer) {int length = byteBuffer.limit(); //获取字节缓冲区的整个长度,这个长度等于通信协议格式的2、3、4段的总长度int headerLength = byteBuffer.getInt(); //从缓冲区中读取4个字节的int类型的数据值 ,这个值就是报文头部的长度byte[] headerData = new byte[headerLength];byteBuffer.get(headerData); //接下来从缓冲区中读取headerLength个字节的数据,这个数据就是报文头部的数据int bodyLength = length - 4 - headerLength;byte[] bodyData = null;if (bodyLength > 0) {bodyData = new byte[bodyLength];byteBuffer.get(bodyData); //接下来读取length-4-headerLength 个字节的数据,这个数据就是报文体的数据}
//接下来将读取到的数据转换成 RemotingCommand 对象
RemotingCommand cmd = RemotingSerializable.decode(headerData, RemotingCommand.class);cmd.body = bodyData;return cmd;}四 、总结
开发任何的socket 长连接的网络程序,涉及服务器与客户端的开发,首先要定义服务端与客户端的通信协议格式,第二根据定义的通信协议格式来进行传输数据的编解码操作。 上述的通信协议格式为常用的通信协议格式。当长连接在设定的间隔时间范围内没有数据传输时,需要按照协议发送心跳包,
心跳包的协议格式也可以按照这种协议格式发送,也可以另外针对发送的心跳包来定义通信协议格式。
RocketMq通信协议格式及编解码 (源码分析)的更多相关文章
- RocketMQ中Broker的HA策略源码分析
Broker的HA策略分为两部分①同步元数据②同步消息数据 同步元数据 在Slave启动时,会启动一个定时任务用来从master同步元数据 if (role == BrokerRole.SLAVE) ...
- RocketMQ中Broker的刷盘源码分析
上一篇博客的最后简单提了下CommitLog的刷盘 [RocketMQ中Broker的消息存储源码分析] (这篇博客和上一篇有很大的联系) Broker的CommitLog刷盘会启动一个线程,不停地 ...
- ffplay源码分析5-图像格式转换
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10311376.html ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg ...
- RocketMQ中PullConsumer的消息拉取源码分析
在PullConsumer中,有关消息的拉取RocketMQ提供了很多API,但总的来说分为两种,同步消息拉取和异步消息拉取 同步消息拉取以同步方式拉取消息都是通过DefaultMQPullConsu ...
- RocketMQ中Broker的启动源码分析(一)
在RocketMQ中,使用BrokerStartup作为启动类,相较于NameServer的启动,Broker作为RocketMQ的核心可复杂得多 [RocketMQ中NameServer的启动源码分 ...
- RocketMQ中Broker的启动源码分析(二)
接着上一篇博客 [RocketMQ中Broker的启动源码分析(一)] 在完成准备工作后,调用start方法: public static BrokerController start(Broker ...
- RocketMQ中Broker的消息存储源码分析
Broker和前面分析过的NameServer类似,需要在Pipeline责任链上通过NettyServerHandler来处理消息 [RocketMQ中NameServer的启动源码分析] 实际上就 ...
- RocketMQ中PullConsumer的启动源码分析
通过DefaultMQPullConsumer作为默认实现,这里的启动过程和Producer很相似,但相比复杂一些 [RocketMQ中Producer的启动源码分析] DefaultMQPullCo ...
- ffplay源码分析6-音频重采样
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10312713.html ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg ...
随机推荐
- 转:nginx+CGI/FASTCGI
简介版: 1.fastcgi与cgi区别:fastcgi通过线程来响应请求,而cgi对每个请求生成一个进程. 2.典型nginx数据传输过程:user->nginx->本地socket(请 ...
- CodeForces 779A Pupils Redistribution
简单题. 因为需要连边的人的个数一样,又要保证和一样,所以必须每个数字的个数都是一样的. #include<map> #include<set> #include<cti ...
- Protocol Buffers 在前端项目中的使用
前言: 公司后端使用的是go语言,想尝试用pb和前端进行交互,于是便有了这一次尝试,共计花了一星期时间,网上能查到的文档几乎都看了一遍,但大多都是教在node环境下如何使用,普通的js环境下很多讲述的 ...
- 2017江苏省省赛 Roads(全局最小割)
Roads 时间限制: 2 Sec 内存限制: 256 MB提交: 6 解决: 2[提交][状态][讨论版] 题目描述 In ICPCCamp, there are n towns conveni ...
- Linux前后台进程切换
(1).Linux前台进程与后台进程的区别 前台进程:是在终端中运行的命令,那么该终端就为进程的控制终端,一旦这个终端关闭,这个进程也随之消失. 后台进程:也叫守护进程(Daemon),是运行在后台的 ...
- [Atcoder Grand Contest 004] Tutorial
Link: AGC004 传送门 A: …… #include <bits/stdc++.h> using namespace std; long long a,b,c; int main ...
- BZOJ 4883 [Lydsy2017年5月月赛]棋盘上的守卫(最小生成环套树森林)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4883 [题目大意] 在一个n*m的棋盘上要放置若干个守卫. 对于n行来说,每行必须恰好 ...
- 【数论】【莫比乌斯反演】【线性筛】bzoj2005 [Noi2010]能量采集
http://blog.csdn.net/Clove_unique/article/details/51089272 Key:1.连接平面上某个整点(a,b)到原点的线段上有gcd(a,b)个整点. ...
- Problem E: 矩阵鞍点
AC代码#include<stdio.h> int main() { ][]; ]; int i,j,t,n; while(scanf("%d",&n)!=EO ...
- [转]Android的ADT与SDK的区别
adt只是一个eclipse的插件,里面可以设置sdk路径 SDK(Software Development Kit): 一般是一些被软件工程师用于为特定的软件包.软件框架.硬件平台.操作 ...