文章目录
- 一、前言
- 二、整体运行:先启动服务端,然后启动客户端,发送三条消息
- 三、客户端和服务端
- 3.1 客户端(重要)
- 3.2 服务端(重要)
- 3.3 编码和解码(了解即可)
- 四、尾声
一、前言
源码下载:https://www.syjshare.com/res/XEE10LTG
二、整体运行:先启动服务端,然后启动客户端,发送三条消息
先启动server
启动客户端,发送三条消息
对于三条消息时,都是client发送,server接收,而且是 channel. 发送的,不是 outBound 发送的,所以 clientHandler 和 serverHandler 都是继承 inBound ,只有 channelRead 方法,用来接收消息
服务端日志
服务收到的消息 reqType 是 0 ,表示 request 请求
客户端日志
步骤1:启动服务端
步骤2:启动客户端,向服务端发送三条消息
步骤3:服务端的ServerHandler channelRead方法收到消息,并立马在 channelRead 方法里面,向客户端发送一条 reqType 是 1 ,表示 Resp 消息,收到三条来自客户端的消息,就向客户端发送三条响应
步骤4:客户端的ClientHandler channelRead方法收到来自服务端的三条响应,直接在自己的console打印了出来
无论是服务端还是客户端,都是 pipeline.addLast 加上了 MessageRecordDecode 和 MessageRecordEncode 两个类,
客户端:MessageRecordEncode
三、客户端和服务端
3.1 客户端(重要)
客户端:
步骤1:拼装MessageRecord对象
步骤2:pipeline中addLast添加了 MessageRecordEncode,会接受即将发送的 MessageRecord 对象,消息头直接 ByteBuf out 发送出去,消息体序列化为byte[]数组(此处使用Java IO ByteArrayOutputStream流),然后 ByteBuf out 发送出去
步骤3:收到服务端的响应,因为 pipeline 中 addLast 添加了 MessageRecordDecode ,会使用 ByteBuf in 接受收到的 byte[] 数组流,然后在 decode 函数中,拼装成 MessageRecord 对象,对象头就直接取出来就好,对象体需要通过 Java IO ByteArrayInputStream 读进来,反序列化为对象
步骤4:client 收到了 decode 反序列的对象:clientHandler仅仅是继承ChannelInboundHandlerAdapter接收消息,inbound,在 console 打印一下
具体如下:
最后看一下日志:
步骤1:拼装 MessageRecord 没有日志
步骤2:编码有一个日志 log.info("==========开始进行消息编码==================");
步骤3:解码有一个日志 log.info("反序列化出来的结果:"+record);
步骤4:打印消息有一个日志 log.info("ent Receive Message:"+record);
最后回顾一下 client pipeline addLast 四个handler
header 直接 getXxx setXxx ,body 需要ByteArrayInputStream读进来,反序列化为对象,ByteArrayOutputStream写出去,序列化为byte[]
ByteArrayOutputStream 写出去,对象序列化为byte[],ByteArrayInputStream 读进来,byte[]反序列化为对象
3.2 服务端(重要)
服务端:
步骤1:收到消息,MessageRecordDecode 类起作用,byte[]数组反序列化为对象bean
步骤2: serverHandler channelRead 消息打印一下
步骤3:发送消息 serverHandler channelRead 里面
步骤4:msg bean不能直接发送,发送前需要编码
具体如下:
最后看一下日志:
步骤1:解码有一个日志 log.info("反序列化出来的结果:"+record);
步骤2:进入 ServerHandler 有一个日志 log.info("Server Receive Message:"+record);
,然后拼装 MessageRecord
步骤3:ServerHandler channelRead 发送没有日志
步骤4:编码有一个日志 log.info("==========开始进行消息编码==================");
最后回顾一下 server pipeline addLast 四个handler
3.3 编码和解码(了解即可)
编码,写出去,对象 变为 二进制流/byte[]数组
编码的目的是要写出去,通过 ObjectOutputStream 写出去,所以要将 对象 变为 二进制流/byte[]数组 ,然后传输到网络上去
protected void encode(ChannelHandlerContext ctx, MessageRecord msg, ByteBuf out)
msg 是收到的bean对象
然后将 bean 对象 序列化 byte[] 数组
out 是发送出去 byte[] 数组
解码函数里面拼装出一个 record 消息对象,如下:
解码,读进来,二进制流/byte[]数组 变为 对象
解码的目的对读进来二进制流处理,通过 ObjectInputStream 读进来,所以要将 二进制流/byte[]数组 变为 对象
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
in 读进来 bytebuf 二进制数组
然后将 二进制数组 变为对象
放到 out 这个 list 里面
四、尾声
看懂代码就行,不难的。
源码下载:https://www.syjshare.com/res/XEE10LTG