├── .gitignore
├── LICENSE
├── README.md
├── netty-in-action
├── README.md
├── docs
│ ├── Netty-in-Action_en.pdf
│ ├── Netty实战.pdf
│ └── pics
│ │ ├── 3-1.png
│ │ ├── 3-3.png
│ │ ├── 3-4.png
│ │ ├── 4-2.png
│ │ ├── 5-1.png
│ │ ├── 5-2.png
│ │ ├── 5-3.png
│ │ ├── 6-3.png
│ │ ├── 6-5.png
│ │ ├── 7-1.png
│ │ ├── 7-2.png
│ │ ├── 7-3.png
│ │ ├── 7-4.png
│ │ ├── 7-5.png
│ │ ├── channelWriter.png
│ │ ├── table-4-1.png
│ │ ├── table-5-1.png
│ │ ├── table-5-5.png
│ │ ├── table-5-7.png
│ │ ├── table-5-8.png
│ │ ├── table-6-3.png
│ │ ├── table-6-5.png
│ │ ├── table-6-8.png
│ │ ├── table-6-9.png
│ │ └── table4-2.png
├── pom.xml
└── src
│ └── main
│ └── java
│ └── org
│ └── lwl
│ └── netty
│ └── chapter
│ ├── five
│ ├── ByteBufExample.java
│ ├── CreateByteBuf.java
│ └── CustomByteBufHolder.java
│ ├── four
│ ├── ChannelOperationExamples.java
│ ├── NettyNioServer.java
│ ├── NettyOioServer.java
│ ├── PlainNioServer.java
│ └── PlainOioServer.java
│ ├── one
│ ├── BlockingIoExample.java
│ └── ConnectExample.java
│ ├── seven
│ └── EventLoopExamples.java
│ ├── six
│ ├── ChannelFutures.java
│ └── OutboundExceptionHandler.java
│ └── two
│ ├── client
│ ├── EchoClient.java
│ └── EchoClientHandler.java
│ └── server
│ ├── EchoServer.java
│ └── EchoServerHandler.java
├── netty-practice
├── README.md
├── docs
│ └── pics
│ │ └── dynamic-ssl.png
├── pom.xml
└── src
│ └── main
│ ├── Resources
│ └── log4j2.xml
│ └── java
│ └── org
│ └── lwl
│ └── netty
│ ├── Config.java
│ ├── DynamicDemoStart.java
│ ├── UdpDemoStart.java
│ ├── comparewrite
│ └── Test.java
│ ├── core
│ ├── CommonUtil.java
│ ├── CustomThreadFactory.java
│ ├── Decoder.java
│ └── Encoder.java
│ ├── dynamic
│ ├── DynamicConfig.java
│ ├── DynamicMsgType.java
│ ├── client
│ │ ├── DynamicClient.java
│ │ ├── DynamicTriggerEvent.java
│ │ └── handler
│ │ │ ├── ClientInitHandler.java
│ │ │ ├── DynamicTriggerHandler.java
│ │ │ ├── HeartbeatClientHandler.java
│ │ │ ├── ITriggerHandler.java
│ │ │ ├── LoginHandler.java
│ │ │ ├── RandomCodeHandler.java
│ │ │ ├── SslHandler.java
│ │ │ └── SymEncryptionHandler.java
│ ├── codec
│ │ ├── DynamicMsgDecoder.java
│ │ ├── DynamicMsgEncoder.java
│ │ └── serialize
│ │ │ ├── DynamicSerializerFactory.java
│ │ │ ├── HeaderSerializer.java
│ │ │ ├── IBodySerializer.java
│ │ │ ├── TailSerializer.java
│ │ │ └── body
│ │ │ ├── DefaultBodySerializer.java
│ │ │ ├── HtReqBodySerializer.java
│ │ │ ├── HtRespBodySerializer.java
│ │ │ ├── LoginReqBodySerializer.java
│ │ │ ├── LoginRespBodySerializer.java
│ │ │ ├── LogoutBodySerializer.java
│ │ │ ├── RandomCodeBodySerializer.java
│ │ │ ├── SslBodySerializer.java
│ │ │ └── SymEncryptionSerializer.java
│ ├── message
│ │ ├── Body.java
│ │ ├── DynamicMessage.java
│ │ ├── Header.java
│ │ ├── Tail.java
│ │ └── body
│ │ │ ├── HeartbeatReqBody.java
│ │ │ ├── HeartbeatRespBody.java
│ │ │ ├── LoginReqBody.java
│ │ │ ├── LoginRespBody.java
│ │ │ ├── LogoutBody.java
│ │ │ ├── RandomCodeBody.java
│ │ │ ├── SslBody.java
│ │ │ └── SymEncryption.java
│ └── server
│ │ ├── DynamicServer.java
│ │ └── handler
│ │ ├── ExceptionHanlder.java
│ │ ├── HeartbeatServerHandler.java
│ │ ├── LoginRespHandler.java
│ │ ├── RandomCodeServerHandler.java
│ │ ├── SslServerHandler.java
│ │ └── SymEncryptionServerHandler.java
│ ├── udp
│ └── Test.java
│ └── util
│ └── Test.java
├── netty-private-protocol
├── README.md
├── docs
│ ├── LengthFieldBasedFrameDecoder.md
│ └── pics
│ │ └── lengthField
│ │ ├── lengthField-1.png
│ │ ├── lengthField-2.png
│ │ ├── lengthField-3.png
│ │ ├── lengthField-4.png
│ │ ├── lengthField-5.png
│ │ └── lengthField-6.png
├── pom.xml
└── src
│ ├── main
│ ├── Resources
│ │ ├── bin
│ │ │ └── buildProto.sh
│ │ ├── data
│ │ │ ├── entertainment.txt
│ │ │ ├── news.txt
│ │ │ └── sports.txt
│ │ ├── log4j2.xml
│ │ ├── netty-private-protocol.properties
│ │ └── proto
│ │ │ ├── Body.proto
│ │ │ ├── Header.proto
│ │ │ ├── HeartbeatReqBody.proto
│ │ │ ├── HeartbeatRespBody.proto
│ │ │ ├── LoginReqBody.proto
│ │ │ ├── LoginRespBody.proto
│ │ │ ├── LogoutBody.proto
│ │ │ ├── ProtocolDataBody.proto
│ │ │ ├── ProtocolMessage.proto
│ │ │ ├── ProtocolSubBody.proto
│ │ │ └── Tail.proto
│ └── java
│ │ └── org
│ │ └── lwl
│ │ └── netty
│ │ ├── NettyServerAndClientStart.java
│ │ ├── ProtobufServerAndClientStart.java
│ │ ├── client
│ │ ├── NettyClient.java
│ │ ├── NettyClientAdapter.java
│ │ ├── ProtobufNettyClient.java
│ │ └── handler
│ │ │ ├── ClientExceptionHandler.java
│ │ │ ├── other
│ │ │ ├── HeartbeatClientHandler.java
│ │ │ ├── LoginReqHandler.java
│ │ │ └── ProtocolMsgSubHandler.java
│ │ │ └── protobuf
│ │ │ ├── HeartbeatClientHandler.java
│ │ │ ├── LoginReqHandler.java
│ │ │ ├── ProtobufClientCodecHelper.java
│ │ │ └── ProtocolMsgSubHandler.java
│ │ ├── codec
│ │ ├── other
│ │ │ ├── IMessageCodecUtil.java
│ │ │ ├── MessageCodecUtilFactory.java
│ │ │ ├── ProtocolDataDecoder.java
│ │ │ ├── ProtocolDataEncoder.java
│ │ │ ├── kryo
│ │ │ │ ├── KryoCodecUtil.java
│ │ │ │ ├── KryoHolder.java
│ │ │ │ ├── KryoReflectionFactory.java
│ │ │ │ └── serialize
│ │ │ │ │ ├── HeaderKryoSerializer.java
│ │ │ │ │ ├── KryoDecoder.java
│ │ │ │ │ ├── KryoEncoder.java
│ │ │ │ │ ├── ProtocolMessageKryoSerializer.java
│ │ │ │ │ ├── TailKryoSerializer.java
│ │ │ │ │ └── body
│ │ │ │ │ ├── DefaultBodyKryoSerializer.java
│ │ │ │ │ ├── HtReqBodyKryoSerializer.java
│ │ │ │ │ ├── HtRespBodyKryoSerializer.java
│ │ │ │ │ ├── LoginReqBodyKryoSerializer.java
│ │ │ │ │ ├── LoginRespBodyKryoSerializer.java
│ │ │ │ │ ├── LogoutBodyKryoSerializer.java
│ │ │ │ │ ├── ProtocolDataBodyKryoSerializer.java
│ │ │ │ │ └── ProtocolSubBodyKryoSerializer.java
│ │ │ └── marshalling
│ │ │ │ ├── MarshallingAdapterFactory.java
│ │ │ │ ├── MarshallingCodecUtil.java
│ │ │ │ ├── MarshallingDecoderAdapter.java
│ │ │ │ ├── MarshallingEncoderAdapter.java
│ │ │ │ ├── MslDecoder.java
│ │ │ │ ├── MslEncoder.java
│ │ │ │ └── serialize
│ │ │ │ ├── HeaderMslSerializer.java
│ │ │ │ ├── IBodyMslSerializer.java
│ │ │ │ ├── TailMslSerializer.java
│ │ │ │ └── body
│ │ │ │ ├── DefaultBodyMslSerializer.java
│ │ │ │ ├── HeartbeatReqBodyMslSerializer.java
│ │ │ │ ├── HeartbeatRespBodyMslSerializer.java
│ │ │ │ ├── LoginReqBodyMslSerializer.java
│ │ │ │ ├── LoginRespBodyMslSerializer.java
│ │ │ │ ├── LogoutBodyMslSerializer.java
│ │ │ │ ├── ProtocolDataBodyMslSerializer.java
│ │ │ │ └── ProtocolSubBodyMslSerializer.java
│ │ └── protobuf
│ │ │ └── ProtobufPostDecoder.java
│ │ ├── config
│ │ ├── BaseConfig.java
│ │ └── ProtocolConfig.java
│ │ ├── constant
│ │ ├── MessageCodecTypeEnum.java
│ │ ├── MessageTypeEnum.java
│ │ ├── ProtocolConstant.java
│ │ └── ProtocolDataType.java
│ │ ├── message
│ │ ├── Body.java
│ │ ├── Header.java
│ │ ├── ProtocolMessage.java
│ │ ├── Tail.java
│ │ ├── body
│ │ │ ├── HeartbeatReqBody.java
│ │ │ ├── HeartbeatRespBody.java
│ │ │ ├── LoginReqBody.java
│ │ │ ├── LoginRespBody.java
│ │ │ ├── LogoutBody.java
│ │ │ ├── ProtocolDataBody.java
│ │ │ └── ProtocolSubBody.java
│ │ └── protobuf
│ │ │ ├── Body.java
│ │ │ ├── Header.java
│ │ │ ├── HeartbeatReqBody.java
│ │ │ ├── HeartbeatRespBody.java
│ │ │ ├── LoginReqBody.java
│ │ │ ├── LoginRespBody.java
│ │ │ ├── LogoutBody.java
│ │ │ ├── ProtocolDataBody.java
│ │ │ ├── ProtocolMessage.java
│ │ │ ├── ProtocolSubBody.java
│ │ │ └── Tail.java
│ │ ├── server
│ │ ├── NettyServer.java
│ │ ├── ProtobufNettyServer.java
│ │ └── handler
│ │ │ ├── ServerExceptionHandler.java
│ │ │ ├── other
│ │ │ ├── HeartbeatServerHandler.java
│ │ │ ├── LoginRespHandler.java
│ │ │ └── ProtocolMsgSendHandler.java
│ │ │ └── protobuf
│ │ │ ├── HeartbeatServerHandler.java
│ │ │ ├── LoginRespHandler.java
│ │ │ ├── ProtobufServerCodecHelper.java
│ │ │ └── ProtocolMsgSendHandler.java
│ │ └── util
│ │ ├── CommonUtil.java
│ │ └── concurrent
│ │ └── CustomThreadFactory.java
│ └── test
│ └── java
│ └── org
│ └── lwl
│ └── netty
│ └── start
│ ├── NettyClientAndServerStart.java
│ ├── NettyClientStart.java
│ └── NettyServerStart.java
├── netty-rpc
├── README.md
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── lwl
│ │ └── netty
│ │ └── Test.java
│ └── test
│ └── java
│ └── org
│ └── lwl
│ └── netty
│ └── Test.java
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .classpath
3 | .project
4 | *.iml
5 | target/
6 | .DS_Store
7 | .gitattributes
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # netty 学习
2 | ```
3 | @author 鲁伟林
4 | 向开源致敬,向优秀前辈代码致敬。
5 | Netty中大量使用NIO技术,满足高性能、高并发要求。进行初步研究,特作此项目。
6 |
7 | 源码地址:https://github.com/thinkingfioa/netty-learning
8 | 本人博客地址: https://blog.csdn.net/thinking_fioa
9 | ```
10 |
11 | TODO
12 |
13 | 1. 动态编码ChannelHandler
14 | 2. AttributeMap使用
15 | 3. blog: Channel的理解。包括死锁问题
16 | 4. udp项目
17 | 5. Netty 接收缓冲区
18 | 6. Netty实现RPC框架
19 | 7. Netty.4x用户指南
20 |
21 | ## 一、为什么要读Netty?
22 |
23 | ## 1. Netty是什么?
24 |
25 | ## 2. Netty特性
26 |
27 | ## 二、 项目结构介绍
28 |
29 | |序号|名称|介绍|
30 | |:---:|:---:|:---:|
31 | |1|netty-private-protocol|基于Netty自定义私有协议的开发|
32 | |2|netty-in-action|阅读《Netty实战》的笔记,记录诸多Netty的特性和自己的理解|
33 | |3|netty-rpc|使用Netty实现RPC框架|
34 | |4|netty-practice|基于Netty中的诸多特性编写案例,帮助理解|
35 |
36 | ## 1. 私有协议开发(netty-private-protocol)
37 | netty-private-protocol是一个利用Netty实现自定义的协议开发,具有非常高的普世参考价值。参考了《Netty权威指南2》中第12章节。并做以下改进:
38 |
39 | 1.《Netty权威指南2》中第12章节,讲解了关于私有协议栈开发。平时开发中具有参考价值,但书本中代码存在较多问题,本人基于文中代码进行调试,成功运行。
40 | 2.实现了基本私有协议栈开发,并成功运行。在此基础上,比较多种编码和解码的速度。
41 | 3.代码中实现了使用了多种编码和解码逻辑。其中有: Marshalling、Kryo、Protobuf、Thrift和messagePack。通过子项目可以学习基于Netty,实现多种编解码器技术。
42 | 4.[子项目文档地址](https://github.com/thinkingfioa/netty-learning/tree/master/netty-private-protocol)
43 |
44 | ## 2. Netty实战
45 | 《Netty实战》是一本好书。讲解非常透彻,能帮助开发人员更好的理解和使用Netty。最近在读第二遍。推荐此书,讲的非常透彻。
46 |
47 | 1. 总结书中多处知识点,方便开发人员理解和使用。同时添加多处自己的理解。如有错误,请指教
48 | 2. [子项目文档地址](https://github.com/thinkingfioa/netty-learning/tree/master/netty-in-action)
49 | 3. 本书分成多个章节,发布于本人的博客专栏,欢迎各位指出不足之处。[Netty专栏地址](https://blog.csdn.net/column/details/22861.html)
50 |
51 | ## 3. RPC框架实现
52 | 基于Netty,实现基本RPC框架
53 |
54 | ## 4. Netty-Practice
55 | Netty-Practice介绍诸多使用Netty的特性,并辅助案例帮助理解。如: ChannelHandler动态编排、AttributeMap的使用或ChannelPrimise等诸多Netty提供的特性。
56 | 详见(地址)[https://github.com/thinkingfioa/netty-learning/tree/master/netty-practice]
57 |
58 | ## 三、Netty 源码学习
59 | Netty源码研究
60 |
61 | # 参考文档
62 | - 1.《Netty权威指南2》
--------------------------------------------------------------------------------
/netty-in-action/docs/Netty-in-Action_en.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/Netty-in-Action_en.pdf
--------------------------------------------------------------------------------
/netty-in-action/docs/Netty实战.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/Netty实战.pdf
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/3-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/3-1.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/3-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/3-3.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/3-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/3-4.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/4-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/4-2.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/5-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/5-1.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/5-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/5-2.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/5-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/5-3.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/6-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/6-3.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/6-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/6-5.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/7-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/7-1.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/7-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/7-2.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/7-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/7-3.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/7-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/7-4.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/7-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/7-5.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/channelWriter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/channelWriter.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/table-4-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/table-4-1.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/table-5-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/table-5-1.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/table-5-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/table-5-5.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/table-5-7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/table-5-7.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/table-5-8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/table-5-8.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/table-6-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/table-6-3.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/table-6-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/table-6-5.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/table-6-8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/table-6-8.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/table-6-9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/table-6-9.png
--------------------------------------------------------------------------------
/netty-in-action/docs/pics/table4-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-in-action/docs/pics/table4-2.png
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/five/CreateByteBuf.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.five;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.buffer.ByteBufAllocator;
5 | import io.netty.buffer.Unpooled;
6 | import io.netty.channel.ChannelHandlerContext;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/6/24
11 | * @description
12 | */
13 |
14 |
15 | public class CreateByteBuf {
16 |
17 | public void createByteBuf(ChannelHandlerContext ctx) {
18 | // 1. 通过Channel创建ByteBuf
19 | ByteBuf buf1 = ctx.channel().alloc().buffer();
20 | // 2. 通过ByteBufAllocator.DEFAULT创建
21 | ByteBuf buf2 = ByteBufAllocator.DEFAULT.buffer();
22 | // 3. 通过Unpooled创建
23 | ByteBuf buf3 = Unpooled.buffer();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/five/CustomByteBufHolder.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.five;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.buffer.DefaultByteBufHolder;
5 |
6 | /**
7 | * 友情提示:建议覆盖DefaultByteBufHolder的所有方法,否则可能出现{@link ClassCastException}
8 | * 希望有更好的方式来实现自定义ByteBuf方式
9 | *
10 | * @author thinking_fioa
11 | * @createTime 2018/6/24
12 | * @description
13 | */
14 |
15 |
16 | public class CustomByteBufHolder extends DefaultByteBufHolder{
17 |
18 | private String protocolName;
19 |
20 | public CustomByteBufHolder(String protocolName, ByteBuf data) {
21 | super(data);
22 | this.protocolName = protocolName;
23 | }
24 |
25 | @Override
26 | public CustomByteBufHolder replace(ByteBuf data) {
27 | return new CustomByteBufHolder(protocolName, data);
28 | }
29 |
30 | @Override
31 | public CustomByteBufHolder retain() {
32 | super.retain();
33 | return this;
34 | }
35 |
36 | @Override
37 | public CustomByteBufHolder touch() {
38 | super.touch();
39 | return this;
40 | }
41 |
42 | @Override
43 | public CustomByteBufHolder touch(Object hint) {
44 | super.touch(hint);
45 | return this;
46 | }
47 |
48 | public String getProtocolName() {
49 | return protocolName;
50 | }
51 |
52 | public void setProtocolName(String protocolName) {
53 | this.protocolName = protocolName;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/four/ChannelOperationExamples.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.four;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.buffer.Unpooled;
5 | import io.netty.channel.Channel;
6 | import io.netty.channel.ChannelFuture;
7 | import io.netty.channel.ChannelFutureListener;
8 | import io.netty.channel.socket.nio.NioSocketChannel;
9 | import io.netty.util.CharsetUtil;
10 |
11 | import java.util.concurrent.Executor;
12 | import java.util.concurrent.Executors;
13 |
14 | /**
15 | * @author thinking_fioa
16 | * @createTime 2018/6/5
17 | * @description 代码清单4-5和4-6
18 | */
19 |
20 |
21 | public class ChannelOperationExamples {
22 | private static final Channel CHANNEL_FROM_SOMEWHERE = new NioSocketChannel();
23 |
24 | /**
25 | * 代码清单4-5 往Channel中写
26 | */
27 | public static void writingToChannel() {
28 | Channel channel = CHANNEL_FROM_SOMEWHERE;
29 | ByteBuf buf = Unpooled.copiedBuffer("your data", CharsetUtil.UTF_8);
30 | ChannelFuture cf = channel.writeAndFlush(buf);
31 | cf.addListener(new ChannelFutureListener() {
32 | @Override
33 | public void operationComplete(ChannelFuture future) {
34 | if (future.isSuccess()) {
35 | System.out.println("Write successful");
36 | } else {
37 | System.err.println("Write error");
38 | future.cause().printStackTrace();
39 | }
40 | }
41 | });
42 | }
43 |
44 | /**
45 | * 代码清单4-6 多个线程同时访问同一个Channel。
46 | * 1. Channel是线程安全。
47 | * 2. 消息将严格按照顺序发送
48 | */
49 | public static void writingToChannelFromManyThreads() {
50 | final Channel channel = CHANNEL_FROM_SOMEWHERE;
51 | final ByteBuf buf = Unpooled.copiedBuffer("your data", CharsetUtil.UTF_8);
52 | Runnable writer = new Runnable() {
53 | @Override
54 | public void run() {
55 | channel.write(buf.duplicate());
56 | }
57 | };
58 | Executor executor = Executors.newCachedThreadPool();
59 |
60 | // write in one thread
61 | executor.execute(writer);
62 |
63 | // write in another thread
64 | executor.execute(writer);
65 | //...
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/four/NettyNioServer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.four;
2 |
3 | import io.netty.bootstrap.ServerBootstrap;
4 | import io.netty.buffer.ByteBuf;
5 | import io.netty.buffer.Unpooled;
6 | import io.netty.channel.*;
7 | import io.netty.channel.nio.NioEventLoopGroup;
8 | import io.netty.channel.socket.SocketChannel;
9 | import io.netty.channel.socket.nio.NioServerSocketChannel;
10 | import io.netty.channel.socket.oio.OioServerSocketChannel;
11 |
12 | import java.net.InetSocketAddress;
13 | import java.nio.charset.Charset;
14 |
15 | /**
16 | * @author thinking_fioa
17 | * @createTime 2018/5/27
18 | * @description 代码清单4-4,Netty非阻塞网络编程
19 | */
20 |
21 |
22 | public class NettyNioServer {
23 | public void server(int port)
24 | throws Exception {
25 | final ByteBuf buf = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hi!\r\n", Charset.forName("UTF-8")));
26 | /**
27 | * 与Netty的BIO第一处不同
28 | */
29 | EventLoopGroup group = new NioEventLoopGroup();
30 | try {
31 | ServerBootstrap b = new ServerBootstrap();
32 | /**
33 | * 与Netty的BIO第二处不同
34 | */
35 | b.group(group).channel(NioServerSocketChannel.class)
36 | .localAddress(new InetSocketAddress(port))
37 | .childHandler(new ChannelInitializer() {
38 | @Override
39 | public void initChannel(SocketChannel ch) throws Exception {
40 | ch.pipeline().addLast( new ChannelInboundHandlerAdapter() {
41 | @Override
42 | public void channelActive(ChannelHandlerContext ctx) throws Exception {
43 | ctx.writeAndFlush(buf.duplicate())
44 | .addListener(ChannelFutureListener.CLOSE);
45 | }
46 | });
47 | }
48 | });
49 | ChannelFuture f = b.bind().sync();
50 | f.channel().closeFuture().sync();
51 | } finally {
52 | group.shutdownGracefully().sync();
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/four/NettyOioServer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.four;
2 |
3 | import io.netty.bootstrap.ServerBootstrap;
4 | import io.netty.buffer.ByteBuf;
5 | import io.netty.buffer.Unpooled;
6 | import io.netty.channel.*;
7 | import io.netty.channel.oio.OioEventLoopGroup;
8 | import io.netty.channel.socket.SocketChannel;
9 | import io.netty.channel.socket.oio.OioServerSocketChannel;
10 |
11 | import java.net.InetSocketAddress;
12 | import java.nio.charset.Charset;
13 |
14 | /**
15 | * @author thinking_fioa
16 | * @createTime 2018/5/27
17 | * @description 代码清单4-3,Netty阻塞网络编程
18 | */
19 |
20 |
21 | public class NettyOioServer {
22 | public void server(int port)
23 | throws Exception {
24 | final ByteBuf buf = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hi!\r\n", Charset.forName("UTF-8")));
25 | /**
26 | * 与Netty的NIO第一处不同
27 | */
28 | EventLoopGroup group = new OioEventLoopGroup();
29 | try {
30 | ServerBootstrap b = new ServerBootstrap();
31 | /**
32 | * 与Netty的NIO第二处不同
33 | */
34 | b.group(group).channel(OioServerSocketChannel.class)
35 | .localAddress(new InetSocketAddress(port))
36 | .childHandler(new ChannelInitializer() {
37 | @Override
38 | public void initChannel(SocketChannel ch) throws Exception {
39 | ch.pipeline().addLast( new ChannelInboundHandlerAdapter() {
40 | @Override
41 | public void channelActive(ChannelHandlerContext ctx) throws Exception {
42 | ctx.writeAndFlush(buf.duplicate())
43 | .addListener(ChannelFutureListener.CLOSE);
44 | }
45 | });
46 | }
47 | });
48 | ChannelFuture f = b.bind().sync();
49 | f.channel().closeFuture().sync();
50 | } finally {
51 | group.shutdownGracefully().sync();
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/four/PlainOioServer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.four;
2 |
3 | import java.io.IOException;
4 | import java.io.OutputStream;
5 | import java.net.ServerSocket;
6 | import java.net.Socket;
7 | import java.nio.charset.Charset;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/5/27
12 | * @description 代码清单4-1,Java原生的阻塞网络编程
13 | */
14 |
15 |
16 | public class PlainOioServer {
17 | public void serve(int port) throws IOException {
18 | final ServerSocket socket = new ServerSocket(port);
19 | try {
20 | for(;;) {
21 | final Socket clientSocket = socket.accept();
22 | System.out.println(
23 | "Accepted connection from " + clientSocket);
24 | new Thread(new Runnable() {
25 | @Override
26 | public void run() {
27 | OutputStream out;
28 | try {
29 | out = clientSocket.getOutputStream();
30 | out.write("Hi!\r\n".getBytes(
31 | Charset.forName("UTF-8")));
32 | out.flush();
33 | clientSocket.close();
34 | } catch (IOException e) {
35 | e.printStackTrace();
36 | } finally {
37 | try {
38 | clientSocket.close();
39 | } catch (IOException ex) {
40 | // ignore on close
41 | }
42 | }
43 | }
44 | }).start();
45 | }
46 | } catch (IOException e) {
47 | e.printStackTrace();
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/one/BlockingIoExample.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.one;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 | import java.io.PrintWriter;
7 | import java.net.ServerSocket;
8 | import java.net.Socket;
9 |
10 | /**
11 | * @author thinking_fioa
12 | * @createTime 2018/5/14
13 | * @description BIO 服务端例子, 代码清单 1-1 阻塞I/O示例
14 | */
15 |
16 |
17 | public class BlockingIoExample {
18 |
19 | public void serve(int port) throws IOException {
20 | ServerSocket serverSocket = new ServerSocket(port);
21 | Socket clientSocket = serverSocket.accept();
22 | BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
23 | PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
24 | String request, response;
25 | while((request = in.readLine()) != null) {
26 | if("Done".equals(request)) {
27 | break;
28 | }
29 | response = processRequest(request);
30 | out.println(response);
31 | }
32 | }
33 |
34 | private String processRequest(String request) {
35 | return "Processed";
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/one/ConnectExample.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.one;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.buffer.Unpooled;
5 | import io.netty.channel.Channel;
6 | import io.netty.channel.ChannelFuture;
7 | import io.netty.channel.ChannelFutureListener;
8 | import io.netty.channel.socket.nio.NioSocketChannel;
9 |
10 | import java.net.InetSocketAddress;
11 | import java.nio.charset.Charset;
12 |
13 | /**
14 | * @author thinking_fioa
15 | * @createTime 2018/5/16
16 | * @description 代码清单1-3/1-4。 连接建立+回调函数
17 | */
18 |
19 |
20 | public class ConnectExample {
21 | private static final Channel CHANNEL_FROM_SOMEWHERE = new NioSocketChannel();
22 |
23 | public static void connect() {
24 | Channel channel = CHANNEL_FROM_SOMEWHERE;
25 |
26 | ChannelFuture future = channel.connect(new InetSocketAddress("127.0.0.1", 9080));
27 | future.addListener(new ChannelFutureListener() {
28 | @Override
29 | public void operationComplete(ChannelFuture future) throws Exception {
30 | if(future.isSuccess()) {
31 | ByteBuf buf = Unpooled.copiedBuffer("hello", Charset.defaultCharset());
32 | ChannelFuture wf = future.channel().writeAndFlush(buf);
33 | // ...
34 | } else {
35 | future.cause().printStackTrace();
36 | }
37 | }
38 | });
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/seven/EventLoopExamples.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.seven;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/8/14
9 | * @description
10 | */
11 |
12 |
13 | public class EventLoopExamples {
14 | /**
15 | * 代码清单 7-1
16 | */
17 | public static void executeTaskInEventLoop() {
18 | boolean terminated = true;
19 |
20 | while (!terminated) {
21 | List readyEvents = blockUntilEventsReady();
22 | for (Runnable ev: readyEvents) {
23 | ev.run();
24 | }
25 | }
26 | }
27 |
28 | public static List blockUntilEventsReady() {
29 | return new ArrayList<>();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/six/ChannelFutures.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.six;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.buffer.Unpooled;
5 | import io.netty.channel.Channel;
6 | import io.netty.channel.ChannelFuture;
7 | import io.netty.channel.ChannelHandlerContext;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/7/15
12 | * @description 代码清单6-13。添加ChannelFutureListener到ChannelFuture
13 | */
14 |
15 |
16 | public class ChannelFutures {
17 | public static void addingChannelFutureListener(ChannelHandlerContext ctx){
18 | Channel channel = ctx.channel();
19 | ByteBuf someMessage = Unpooled.buffer();
20 | //...
21 | io.netty.channel.ChannelFuture future = channel.write(someMessage);
22 | future.addListener((ChannelFuture f) -> {
23 | if(f.isSuccess()) {
24 | // operation success.
25 | System.out.println("success.");
26 | }else {
27 | // operation fail
28 | f.cause().printStackTrace();
29 | }
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/six/OutboundExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.six;
2 |
3 | import io.netty.channel.ChannelFuture;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.channel.ChannelOutboundHandlerAdapter;
6 | import io.netty.channel.ChannelPromise;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/7/15
11 | * @description 代码清单6-14,添加ChannelFutureListener到ChannelPromise
12 | */
13 |
14 | public class OutboundExceptionHandler extends ChannelOutboundHandlerAdapter{
15 |
16 | @Override
17 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
18 | ctx.write(msg, promise);
19 | promise.addListener((ChannelFuture f) -> {
20 | if (f.isSuccess()) {
21 | // operation success.
22 | System.out.println("success.");
23 | }else {
24 | // operation fail
25 | f.cause().printStackTrace();
26 | }
27 | });
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/two/client/EchoClient.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.two.client;
2 |
3 | import io.netty.bootstrap.Bootstrap;
4 | import io.netty.channel.ChannelFuture;
5 | import io.netty.channel.ChannelInitializer;
6 | import io.netty.channel.EventLoopGroup;
7 | import io.netty.channel.nio.NioEventLoopGroup;
8 | import io.netty.channel.socket.SocketChannel;
9 | import io.netty.channel.socket.nio.NioSocketChannel;
10 |
11 | import java.net.InetSocketAddress;
12 |
13 | /**
14 | * @author thinking_fioa
15 | * @createTime 2018/5/16
16 | * @description 代码清单 2-4,客户端引导类
17 | */
18 |
19 |
20 | public class EchoClient {
21 | private final String host;
22 | private final int port;
23 |
24 | public EchoClient(String host, int port) {
25 | this.host = host;
26 | this.port = port;
27 | }
28 |
29 | public void start()
30 | throws Exception {
31 | EventLoopGroup group = new NioEventLoopGroup();
32 | try {
33 | Bootstrap b = new Bootstrap();
34 | b.group(group)
35 | .channel(NioSocketChannel.class)
36 | .remoteAddress(new InetSocketAddress(host, port))
37 | .handler(new ChannelInitializer() {
38 | @Override
39 | public void initChannel(SocketChannel ch)
40 | throws Exception {
41 | ch.pipeline().addLast(
42 | new EchoClientHandler());
43 | }
44 | });
45 | // 下面两行代码可以删除
46 | ChannelFuture f = b.connect().sync();
47 | f.channel().closeFuture().sync();
48 | } finally {
49 | group.shutdownGracefully().sync();
50 | }
51 | }
52 |
53 | public static void main(String[] args) throws Exception {
54 |
55 | new EchoClient("127.0.0.1", 9080).start();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/two/client/EchoClientHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.two.client;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.buffer.Unpooled;
5 | import io.netty.channel.ChannelHandlerContext;
6 | import io.netty.channel.SimpleChannelInboundHandler;
7 | import io.netty.util.CharsetUtil;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/5/21
12 | * @description 代码清单2-3 客户端业务处理Handler
13 | */
14 |
15 |
16 | public class EchoClientHandler extends SimpleChannelInboundHandler {
17 |
18 | /**
19 | * 链路激活事件
20 | */
21 | @Override
22 | public void channelActive(ChannelHandlerContext ctx) {
23 | ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!",
24 | CharsetUtil.UTF_8));
25 | }
26 |
27 | /**
28 | * 有消息读取
29 | * @param ctx
30 | * @param in
31 | */
32 | @Override
33 | public void channelRead0(ChannelHandlerContext ctx, ByteBuf in) {
34 | System.out.println(
35 | "Client received: " + in.toString(CharsetUtil.UTF_8));
36 | }
37 |
38 | @Override
39 | public void exceptionCaught(ChannelHandlerContext ctx,
40 | Throwable cause) {
41 | cause.printStackTrace();
42 | ctx.close();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/two/server/EchoServer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.two.server;
2 |
3 | import io.netty.bootstrap.ServerBootstrap;
4 | import io.netty.channel.ChannelFuture;
5 | import io.netty.channel.ChannelInitializer;
6 | import io.netty.channel.EventLoopGroup;
7 | import io.netty.channel.nio.NioEventLoopGroup;
8 | import io.netty.channel.socket.SocketChannel;
9 | import io.netty.channel.socket.nio.NioServerSocketChannel;
10 |
11 | import java.net.InetSocketAddress;
12 |
13 | /**
14 | * @author thinking_fioa
15 | * @createTime 2018/5/16
16 | * @description 代码清单 2-2,服务端引导器
17 | */
18 |
19 |
20 | public class EchoServer {
21 | private final int port;
22 |
23 | public EchoServer(int port) {
24 | this.port = port;
25 | }
26 |
27 | public static void main(String[] args)
28 | throws Exception {
29 |
30 | int port = 9080;
31 | new EchoServer(port).start();
32 | }
33 |
34 | public void start() throws Exception {
35 | EventLoopGroup group = new NioEventLoopGroup();
36 | try {
37 | ServerBootstrap b = new ServerBootstrap();
38 | b.group(group)
39 | .channel(NioServerSocketChannel.class)
40 | .localAddress(new InetSocketAddress(port))
41 | .childHandler(new ChannelInitializer() {
42 | @Override
43 | public void initChannel(SocketChannel ch) throws Exception {
44 | ch.pipeline().addLast(new EchoServerHandler());
45 | }
46 | });
47 | // 实际项目中,b.bind().sync()可以省略
48 | ChannelFuture f = b.bind().sync();
49 | System.out.println(EchoServer.class.getName() +
50 | " started and listening for connections on " + f.channel().localAddress());
51 | // 实际项目中,f.channel().closeFuture().sync()可以省略
52 | f.channel().closeFuture().sync();
53 | } finally {
54 | group.shutdownGracefully().sync();
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/netty-in-action/src/main/java/org/lwl/netty/chapter/two/server/EchoServerHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.chapter.two.server;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.buffer.Unpooled;
5 | import io.netty.channel.ChannelFutureListener;
6 | import io.netty.channel.ChannelHandler;
7 | import io.netty.channel.ChannelHandlerContext;
8 | import io.netty.channel.ChannelInboundHandlerAdapter;
9 | import io.netty.util.CharsetUtil;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/5/21
14 | * @description 代码清单 2-1,服务端处理Handler
15 | */
16 |
17 | @ChannelHandler.Sharable
18 | public class EchoServerHandler extends ChannelInboundHandlerAdapter{
19 |
20 | /**
21 | * 每次传入的消息都要调用
22 | */
23 | @Override
24 | public void channelRead(ChannelHandlerContext ctx, Object msg) {
25 | ByteBuf in = (ByteBuf) msg;
26 | System.out.println(
27 | "Server received: " + in.toString(CharsetUtil.UTF_8));
28 | ctx.write(in);
29 | }
30 |
31 | /**
32 | * 读完当前批量中的最后一条数据后,触发channelReadComplete(...)方法
33 | */
34 | @Override
35 | public void channelReadComplete(ChannelHandlerContext ctx)
36 | throws Exception {
37 | ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
38 | .addListener(ChannelFutureListener.CLOSE);
39 | }
40 |
41 | /**
42 | * 异常捕获
43 | */
44 | @Override
45 | public void exceptionCaught(ChannelHandlerContext ctx,
46 | Throwable cause) {
47 | cause.printStackTrace();
48 | ctx.close();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/netty-practice/docs/pics/dynamic-ssl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-practice/docs/pics/dynamic-ssl.png
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/Config.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty;
2 |
3 | import java.nio.charset.Charset;
4 |
5 | /**
6 | * @author thinking_fioa
7 | * @createTime 2018/7/28
8 | * @description
9 | */
10 |
11 |
12 | public final class Config {
13 | private Config() {
14 | throw new IllegalAccessError("static class, can not constructor.");
15 | }
16 |
17 | public static String getCharsetFormatStr() {
18 | return "UTF-8";
19 | }
20 |
21 | public static Charset getCharsetFormat() {
22 | return Charset.forName(getCharsetFormatStr());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/DynamicDemoStart.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty;
2 |
3 | import org.lwl.netty.dynamic.client.DynamicClient;
4 | import org.lwl.netty.dynamic.server.DynamicServer;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/7/11
9 | * @description 动态编排ChannelHandler的启动main
10 | */
11 |
12 |
13 | public class DynamicDemoStart {
14 |
15 | public static void main(String [] args) throws InterruptedException {
16 | // Dynamic服务端以单个线程启动
17 | new Thread(new Runnable() {
18 | @Override
19 | public void run() {
20 | new DynamicServer().start();
21 | }
22 | }).start();
23 |
24 | Thread.sleep(6000);
25 |
26 | // Dynamic客户端以单个线程启动
27 | new Thread(new Runnable() {
28 | @Override
29 | public void run() {
30 | new DynamicClient().start();
31 | }
32 | }).start();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/UdpDemoStart.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty;
2 |
3 | /**
4 | * @author thinking_fioa
5 | * @createTime 2018/7/23
6 | * @description Udp案例启动类
7 | */
8 |
9 |
10 | public class UdpDemoStart {
11 | public static void main() {
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/comparewrite/Test.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.comparewrite;
2 |
3 | /**
4 | * @author thinking_fioa
5 | * @createTime 2018/7/25
6 | * @description
7 | */
8 |
9 |
10 | public class Test {
11 | }
12 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/core/CommonUtil.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.core;
2 |
3 | import io.netty.buffer.ByteBuf;
4 |
5 | import java.time.LocalDateTime;
6 | import java.time.format.DateTimeFormatter;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/7/28
11 | * @description
12 | */
13 |
14 |
15 | public class CommonUtil {
16 | private CommonUtil() {
17 | throw new IllegalAccessError("can not use constructor about static class");
18 | }
19 |
20 | /**
21 | * 计算checkSum
22 | * @return
23 | */
24 | public static int calCheckSum(ByteBuf byteBuf, int length) {
25 | if(length <=0) {
26 | throw new IllegalArgumentException("length <= 0");
27 | }
28 | byte checkSum = 0;
29 | length = Math.min(length, byteBuf.writerIndex());
30 | for(int i = 0; i value == null, 写入-1. 2> value == "", 写入0.
17 | */
18 | public static void writeString(ByteBuf outByteBuf, String value) {
19 | if(null == value) {
20 | outByteBuf.writeInt(-1);
21 |
22 | return ;
23 | }
24 |
25 | if(value.isEmpty()) {
26 | outByteBuf.writeInt(0);
27 |
28 | return;
29 | }
30 | byte[] valueBytes = value.getBytes(Config.getCharsetFormat());
31 | outByteBuf.writeInt(valueBytes.length);
32 | outByteBuf.writeBytes(valueBytes);
33 | }
34 |
35 | public static void writeBytes(ByteBuf outByteBuf, byte[] bytes) {
36 | outByteBuf.writeBytes(bytes);
37 | }
38 |
39 | /**
40 | * 序列化{@code Integer} 值
41 | */
42 | public static void writeInt(ByteBuf outByteBuf, int value) {
43 | outByteBuf.writeInt(value);
44 | }
45 |
46 | public static void writeLong(ByteBuf outByteBuf, long value) {
47 | outByteBuf.writeLong(value);
48 | }
49 |
50 | public static void writeByte(ByteBuf outByteBuf, byte value) {
51 | outByteBuf.writeByte(value);
52 | }
53 |
54 | public static void writeDouble(ByteBuf outByteBuf, double value) {
55 | outByteBuf.writeDouble(value);
56 | }
57 |
58 | public static void writeShort(ByteBuf outByteBuf, short value) {
59 | outByteBuf.writeShort(value);
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/DynamicConfig.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic;
2 |
3 | /**
4 | * @author thinking_fioa
5 | * @createTime 2018/8/6
6 | * @description
7 | */
8 |
9 |
10 | public class DynamicConfig {
11 | private DynamicConfig() {
12 | throw new UnsupportedOperationException("static class");
13 | }
14 |
15 | public static String getUserName() {
16 | return "thinking";
17 | }
18 |
19 | public static String getPasswd() {
20 | return "fioa";
21 | }
22 |
23 | public static String getSslVersion() {
24 | return "3.2.2";
25 | }
26 |
27 | public static String getSymEncryption() {
28 | return "AES";
29 | }
30 |
31 | public static int getHtMultiple() {
32 | return 6;
33 | }
34 |
35 | public static String getServerIp() {
36 | return "127.0.0.1";
37 | }
38 |
39 | public static int getPort() {
40 | return 8989;
41 | }
42 |
43 | public static long getHtInterval() {
44 | return 5;
45 | }
46 |
47 | public static int getMaxFramelength() {
48 | // 4K
49 | return 4 * 1024;
50 | }
51 |
52 | public static int getLengthFieldOffset() {
53 | return 0;
54 | }
55 |
56 | public static int getLengthfieldLength() {
57 | return 4;
58 | }
59 |
60 | public static int getLengthAdjustment() {
61 | return -4;
62 | }
63 |
64 | public static int getInitialBytesToStrip() {
65 | return 0;
66 | }
67 |
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/DynamicMsgType.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/7/28
9 | * @description
10 | */
11 |
12 |
13 | public enum DynamicMsgType {
14 |
15 | /**
16 | * Unknown 消息类型
17 | */
18 | UNKNOWN((byte)0, "unknown"),
19 |
20 | /**
21 | * SSL版本信息
22 | */
23 | SSL((byte)1, "SSL"),
24 |
25 | /**
26 | * 对称加密
27 | */
28 | SYM_ENCRYPTION((byte)2, "SymEncryption"),
29 |
30 | /**
31 | * 随机数生成密钥
32 | */
33 | RANDOM_CODE((byte)3, "RandomCode"),
34 |
35 | /**
36 | * 登陆消息
37 | */
38 | LOGIN_REQ((byte)4, "loginReq"),
39 |
40 | /**
41 | * 登陆响应
42 | */
43 | LOGIN_RESP((byte)5, "loginResp"),
44 |
45 | /**
46 | * 注销
47 | */
48 | LOGOUT((byte)6, "logout"),
49 |
50 | /**
51 | * 心跳请求
52 | */
53 | HEARTBEAT_REQ((byte)7, "heartbeatReq"),
54 |
55 | /**
56 | * 心跳响应
57 | */
58 | HEARTBEAT_RESP((byte)8, "heartbeatResp");
59 |
60 |
61 | private final byte msgType;
62 | private final String desc;
63 |
64 | DynamicMsgType(byte msgType, String desc) {
65 | this.msgType = msgType;
66 | this.desc = desc;
67 | }
68 |
69 | /**
70 | * 根据msgType类型,获取{@code DynamicMsgType}
71 | * 使用Hashmap缓存,提高缓存
72 | * @param msgType
73 | * @return
74 | */
75 | public static DynamicMsgType getMsgTypeEnum(final Byte msgType) {
76 | if(null == msgType ) {
77 | return null;
78 | }
79 |
80 | return DynamicMsgTypeHolder.getMsgTypeEnum(msgType);
81 | }
82 |
83 | public byte getMsgType() {
84 | return msgType;
85 | }
86 |
87 | @Override
88 | public String toString() {
89 | return desc;
90 | }
91 |
92 | private static class DynamicMsgTypeHolder {
93 | private static Map msgTypeMap;
94 | static {
95 | msgTypeMap = new HashMap<>();
96 | for(DynamicMsgType type: DynamicMsgType.values()) {
97 | msgTypeMap.put(type.getMsgType(), type);
98 | }
99 | }
100 |
101 | public static DynamicMsgType getMsgTypeEnum(Byte key) {
102 | if(msgTypeMap.containsKey(key)) {
103 | return msgTypeMap.get(key);
104 | }
105 | return null;
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/client/DynamicClient.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.client;
2 |
3 | import io.netty.bootstrap.Bootstrap;
4 | import io.netty.channel.ChannelInitializer;
5 | import io.netty.channel.EventLoopGroup;
6 | import io.netty.channel.nio.NioEventLoopGroup;
7 | import io.netty.channel.socket.SocketChannel;
8 | import io.netty.channel.socket.nio.NioSocketChannel;
9 | import org.apache.logging.log4j.LogManager;
10 | import org.apache.logging.log4j.Logger;
11 | import org.lwl.netty.core.CustomThreadFactory;
12 | import org.lwl.netty.dynamic.DynamicConfig;
13 | import org.lwl.netty.dynamic.client.handler.ClientInitHandler;
14 | import org.lwl.netty.dynamic.client.handler.DynamicTriggerHandler;
15 | import org.lwl.netty.dynamic.codec.DynamicMsgDecoder;
16 | import org.lwl.netty.dynamic.codec.DynamicMsgEncoder;
17 |
18 | /**
19 | * @author thinking_fioa
20 | * @createTime 2018/7/28
21 | * @description
22 | */
23 |
24 |
25 | public class DynamicClient {
26 | private static final Logger LOGGER = LogManager.getLogger(DynamicClient.class);
27 |
28 | private EventLoopGroup group = new NioEventLoopGroup(1, new CustomThreadFactory("DynamicClientGroup", true));
29 |
30 | private void connect(String ip, int port) {
31 | Bootstrap bootstrap = new Bootstrap();
32 | bootstrap.group(group).channel(NioSocketChannel.class)
33 | .handler(new ChildChannelHandler());
34 | bootstrap.connect(ip, port).addListener((future) -> {
35 | if(future.isSuccess()) {
36 | LOGGER.info("connect {}:{} success.", ip, port);
37 | } else {
38 | LOGGER.error("connect {}:{} fail",ip, port, future.cause());
39 | }
40 | });
41 | }
42 |
43 | public void start() {
44 | connect(DynamicConfig.getServerIp(), DynamicConfig.getPort());
45 | }
46 |
47 | public void quit() {
48 | if(null != group) {
49 | group.shutdownGracefully();
50 | }
51 | }
52 |
53 | private static class ChildChannelHandler extends ChannelInitializer {
54 | @Override
55 | protected void initChannel(SocketChannel ch) throws Exception {
56 | // 初始化只有4个Handler,其他的Handler动态加入到Pipeline
57 | ch.pipeline().addLast(new DynamicMsgDecoder());
58 | ch.pipeline().addLast(new DynamicMsgEncoder());
59 | ch.pipeline().addLast(new ClientInitHandler());
60 | ch.pipeline().addLast(DynamicTriggerHandler.class.getSimpleName(), new DynamicTriggerHandler());
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/client/handler/ClientInitHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.client.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.dynamic.client.DynamicTriggerEvent;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/7/28
12 | * @description
13 | */
14 |
15 |
16 | public class ClientInitHandler extends ChannelInboundHandlerAdapter{
17 | private static final Logger LOGGER = LogManager.getLogger(ClientInitHandler.class);
18 |
19 | @Override
20 | public void channelActive(ChannelHandlerContext ctx) throws Exception {
21 | LOGGER.info("active channel {}", ctx.channel().remoteAddress());
22 | ctx.fireUserEventTriggered(DynamicTriggerEvent.SSL_EVENT);
23 | }
24 |
25 | @Override
26 | public void channelInactive(ChannelHandlerContext ctx) throws Exception {
27 | LOGGER.info("inactive channel {}", ctx.channel().remoteAddress());
28 | ctx.fireChannelInactive();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/client/handler/DynamicTriggerHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.client.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.dynamic.client.DynamicTriggerEvent;
8 |
9 |
10 | /**
11 | * @author thinking_fioa
12 | * @createTime 2018/8/6
13 | * @description 动态添加Handler
14 | */
15 |
16 |
17 | public class DynamicTriggerHandler extends ChannelInboundHandlerAdapter{
18 |
19 | private static final Logger LOGGER = LogManager.getLogger(DynamicTriggerHandler.class);
20 |
21 | @Override
22 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
23 | if(evt instanceof DynamicTriggerEvent) {
24 | DynamicTriggerEvent triggerEvent = (DynamicTriggerEvent)evt;
25 | LOGGER.info("trigger DynamicTrigger {}", triggerEvent);
26 |
27 | triggerEvent.trigger(ctx, DynamicTriggerHandler.class);
28 | } else {
29 | super.userEventTriggered(ctx, evt);
30 | }
31 | }
32 |
33 | @Override
34 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
35 | throws Exception {
36 | LOGGER.error("happen unknown exception.", cause);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/client/handler/HeartbeatClientHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.client.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import io.netty.handler.timeout.IdleState;
6 | import io.netty.handler.timeout.IdleStateEvent;
7 | import org.apache.logging.log4j.LogManager;
8 | import org.apache.logging.log4j.Logger;
9 | import org.lwl.netty.dynamic.DynamicConfig;
10 | import org.lwl.netty.dynamic.DynamicMsgType;
11 | import org.lwl.netty.dynamic.message.DynamicMessage;
12 | import org.lwl.netty.dynamic.message.body.HeartbeatReqBody;
13 |
14 | /**
15 | * @author thinking_fioa
16 | * @createTime 2018/7/28
17 | * @description
18 | */
19 |
20 |
21 | public class HeartbeatClientHandler extends ChannelInboundHandlerAdapter implements ITriggerHandler{
22 | private static final Logger LOGGER = LogManager.getLogger(HeartbeatClientHandler.class);
23 | private int lossConnectTime = 0;
24 |
25 | @Override
26 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
27 | if(evt instanceof IdleStateEvent) {
28 | IdleStateEvent event = (IdleStateEvent)evt;
29 | if(event.state() == IdleState.READER_IDLE) {
30 | lossConnectTime ++;
31 | if(lossConnectTime > DynamicConfig.getHtMultiple()) {
32 | LOGGER.error("heartbeat timeout. close channel {}", ctx.channel().remoteAddress());
33 | ctx.close();
34 | return;
35 | }
36 | } else if(event.state() == IdleState.WRITER_IDLE) {
37 | LOGGER.warn("heartbeat timeout. lossCount {}", lossConnectTime);
38 | ctx.writeAndFlush(buildHtReqMsg());
39 | }
40 | } else {
41 | ctx.fireUserEventTriggered(evt);
42 | }
43 | }
44 |
45 | @Override
46 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
47 | DynamicMessage message = (DynamicMessage) msg;
48 | final DynamicMsgType msgType = message.getHeader().getMsgType();
49 | lossConnectTime = 0;
50 | if(DynamicMsgType.HEARTBEAT_RESP.equals(msgType)) {
51 | LOGGER.debug("receive heartbeat resp");
52 | return;
53 | } else {
54 | ctx.fireChannelRead(msg);
55 | }
56 | }
57 |
58 | private DynamicMessage buildHtReqMsg() {
59 | HeartbeatReqBody htReqBody = new HeartbeatReqBody();
60 |
61 | return DynamicMessage.createMsgOfEncode(htReqBody);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/client/handler/ITriggerHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.client.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 |
5 | /**
6 | * @author thinking_fioa
7 | * @createTime 2018/8/12
8 | * @description
9 | */
10 |
11 |
12 | public interface ITriggerHandler {
13 | default void launch(ChannelHandlerContext ctx) {
14 | //do nothing
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/client/handler/LoginHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.client.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.dynamic.DynamicConfig;
8 | import org.lwl.netty.dynamic.DynamicMsgType;
9 | import org.lwl.netty.dynamic.client.DynamicTriggerEvent;
10 | import org.lwl.netty.dynamic.message.DynamicMessage;
11 | import org.lwl.netty.dynamic.message.body.LoginReqBody;
12 |
13 | /**
14 | * @author thinking_fioa
15 | * @createTime 2018/7/28
16 | * @description 发送登录请求
17 | */
18 |
19 |
20 | public class LoginHandler extends ChannelInboundHandlerAdapter implements ITriggerHandler{
21 | private static final Logger LOGGER = LogManager.getLogger(LoginHandler.class);
22 |
23 | private final String USERNAME = DynamicConfig.getUserName();
24 | private final String PASSWD = DynamicConfig.getPasswd();
25 |
26 | @Override
27 | public void launch(ChannelHandlerContext ctx) {
28 | LOGGER.info("login sent.");
29 | ctx.writeAndFlush(buildLoginReqBody());
30 | }
31 |
32 | @Override
33 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
34 | DynamicMessage message = (DynamicMessage) msg;
35 | final DynamicMsgType msgType = message.getHeader().getMsgType();
36 | if(DynamicMsgType.LOGIN_RESP.equals(msgType)) {
37 | // 客户端接收到登录响应,启动心跳
38 | LOGGER.info("receive login resp. launch heartbeat.");
39 | ctx.fireUserEventTriggered(DynamicTriggerEvent.HEARTBEAT_EVENT);
40 | } else {
41 | ctx.fireChannelRead(msg);
42 | }
43 | }
44 |
45 | private DynamicMessage buildLoginReqBody() {
46 | LoginReqBody loginReqBody = new LoginReqBody();
47 | loginReqBody.setUserName(USERNAME);
48 | loginReqBody.setPassword(PASSWD);
49 |
50 | return DynamicMessage.createMsgOfEncode(loginReqBody);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/client/handler/RandomCodeHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.client.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.dynamic.message.DynamicMessage;
8 | import org.lwl.netty.dynamic.message.body.RandomCodeBody;
9 |
10 | /**
11 | * @author thinking_fioa
12 | * @createTime 2018/7/28
13 | * @description 产生随机码,使用服务端密钥加密后,发送至服务器
14 | */
15 |
16 |
17 | public class RandomCodeHandler extends ChannelInboundHandlerAdapter implements ITriggerHandler{
18 | private static final Logger LOGGER = LogManager.getLogger(RandomCodeHandler.class);
19 |
20 | private static final String RANDOM_CODE = "luweilin";
21 |
22 | @Override
23 | public void launch(ChannelHandlerContext ctx) {
24 | LOGGER.info("randomCode sent.");
25 | ctx.writeAndFlush(buildRandomCodeBody());
26 | // 发起登录请求
27 | LoginHandler loginHandler = new LoginHandler();
28 | ctx.pipeline().addBefore(DynamicTriggerHandler.class.getSimpleName(), LoginHandler.class.getSimpleName(), loginHandler);
29 | loginHandler.launch(ctx);
30 | }
31 |
32 | private DynamicMessage buildRandomCodeBody() {
33 | RandomCodeBody randomCodeBody = new RandomCodeBody();
34 | randomCodeBody.setRandomCode(RANDOM_CODE);
35 |
36 | return DynamicMessage.createMsgOfEncode(randomCodeBody);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/client/handler/SslHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.client.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.dynamic.DynamicConfig;
8 | import org.lwl.netty.dynamic.DynamicMsgType;
9 | import org.lwl.netty.dynamic.client.DynamicTriggerEvent;
10 | import org.lwl.netty.dynamic.message.DynamicMessage;
11 | import org.lwl.netty.dynamic.message.body.SslBody;
12 |
13 | /**
14 | * @author thinking_fioa
15 | * @createTime 2018/7/28
16 | * @description 发送Client端的SSL版本信息
17 | */
18 |
19 |
20 | public class SslHandler extends ChannelInboundHandlerAdapter implements ITriggerHandler{
21 | private static final Logger LOGGER = LogManager.getLogger(SslHandler.class);
22 |
23 | private static final String SSL_VERSION = DynamicConfig.getSslVersion();
24 |
25 | @Override
26 | public void launch(ChannelHandlerContext ctx) {
27 | LOGGER.info("ssl sent.");
28 | ctx.writeAndFlush(buildSslBody());
29 | }
30 |
31 | @Override
32 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
33 | DynamicMessage message = (DynamicMessage) msg;
34 | final DynamicMsgType msgType = message.getHeader().getMsgType();
35 | if(DynamicMsgType.SSL.equals(msgType)) {
36 | // 客户端接收到ssl消息后,启动对称加密Handler
37 | LOGGER.info("receive ssl resp. launch symEncryption.");
38 | ctx.fireUserEventTriggered(DynamicTriggerEvent.SYM_ENCRYPTION_EVENT);
39 | } else {
40 | ctx.fireChannelRead(msg);
41 | }
42 | }
43 |
44 | private DynamicMessage buildSslBody() {
45 | SslBody sslBody = new SslBody();
46 | sslBody.setSslVersion(SSL_VERSION);
47 |
48 | return DynamicMessage.createMsgOfEncode(sslBody);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/client/handler/SymEncryptionHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.client.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.dynamic.DynamicConfig;
8 | import org.lwl.netty.dynamic.DynamicMsgType;
9 | import org.lwl.netty.dynamic.client.DynamicTriggerEvent;
10 | import org.lwl.netty.dynamic.message.DynamicMessage;
11 | import org.lwl.netty.dynamic.message.body.SymEncryption;
12 |
13 | /**
14 | * @author thinking_fioa
15 | * @createTime 2018/7/28
16 | * @description 发送Client端支持的对称加密方案
17 | */
18 |
19 |
20 | public class SymEncryptionHandler extends ChannelInboundHandlerAdapter implements ITriggerHandler{
21 | private static final Logger LOGGER = LogManager.getLogger(SymEncryptionHandler.class);
22 |
23 | private static final String SYM_ENCRYPTION = DynamicConfig.getSymEncryption();
24 |
25 | @Override
26 | public void launch(ChannelHandlerContext ctx) {
27 | LOGGER.info("symEncryption sent.");
28 | ctx.writeAndFlush(buildSymEncryption());
29 | }
30 |
31 | @Override
32 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
33 | DynamicMessage message = (DynamicMessage) msg;
34 | final DynamicMsgType msgType = message.getHeader().getMsgType();
35 | if(DynamicMsgType.SYM_ENCRYPTION.equals(msgType)) {
36 | // 客户端接收到symEncryption消息后,启动随机数加密Handler
37 | LOGGER.info("receive symEncryption resp. launch randomCode.");
38 | ctx.fireUserEventTriggered(DynamicTriggerEvent.RANDOM_CODE_EVENT);
39 | } else {
40 | ctx.fireChannelRead(msg);
41 | }
42 | }
43 |
44 | public DynamicMessage buildSymEncryption() {
45 | SymEncryption symEncryption = new SymEncryption();
46 | symEncryption.setSymEncryptionMethod(SYM_ENCRYPTION);
47 |
48 | return DynamicMessage.createMsgOfEncode(symEncryption);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/DynamicSerializerFactory.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize;
2 |
3 | import org.lwl.netty.dynamic.DynamicMsgType;
4 | import org.lwl.netty.dynamic.codec.serialize.body.*;
5 | import org.lwl.netty.dynamic.message.Body;
6 |
7 | import java.util.EnumMap;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/7/29
12 | * @description
13 | */
14 |
15 |
16 | public final class DynamicSerializerFactory {
17 |
18 | private DynamicSerializerFactory() {
19 | throw new IllegalAccessError("can not use constructor.");
20 | }
21 |
22 | private static EnumMap> bodySerializerMap = new EnumMap<>(DynamicMsgType.class);
23 |
24 | static {
25 | bodySerializerMap.put(DynamicMsgType.UNKNOWN, DefaultBodySerializer.getInstance());
26 | bodySerializerMap.put(DynamicMsgType.SSL, SslBodySerializer.getInstance());
27 | bodySerializerMap.put(DynamicMsgType.SYM_ENCRYPTION, SymEncryptionSerializer.getInstance());
28 | bodySerializerMap.put(DynamicMsgType.RANDOM_CODE, RandomCodeBodySerializer.getInstance());
29 | bodySerializerMap.put(DynamicMsgType.LOGIN_REQ, LoginReqBodySerializer.getInstance());
30 | bodySerializerMap.put(DynamicMsgType.LOGIN_RESP, LoginRespBodySerializer.getInstance());
31 | bodySerializerMap.put(DynamicMsgType.LOGOUT, LogoutBodySerializer.getInstance());
32 | bodySerializerMap.put(DynamicMsgType.HEARTBEAT_REQ, HtReqBodySerializer.getInstance());
33 | bodySerializerMap.put(DynamicMsgType.HEARTBEAT_RESP, HtRespBodySerializer.getInstance());
34 | }
35 |
36 | public static IBodySerializer extends Body> getBodySerializer(final DynamicMsgType msgType) {
37 | IBodySerializer extends Body> bodySerializer = bodySerializerMap.get(msgType);
38 |
39 | return null != bodySerializer ? bodySerializer: DefaultBodySerializer.getInstance();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/HeaderSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.core.Decoder;
5 | import org.lwl.netty.core.Encoder;
6 | import org.lwl.netty.dynamic.DynamicMsgType;
7 | import org.lwl.netty.dynamic.message.Header;
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/7/29
11 | * @description
12 | */
13 |
14 | public class HeaderSerializer {
15 | private static final HeaderSerializer INSTANCE = new HeaderSerializer();
16 | private HeaderSerializer(){}
17 |
18 | public static HeaderSerializer getInstance() {
19 | return INSTANCE;
20 | }
21 |
22 | public void serialize(ByteBuf outByteBuf, Header header) throws Exception {
23 | Encoder.writeLong(outByteBuf, header.getMsgNum());
24 | Encoder.writeByte(outByteBuf, header.getMsgType().getMsgType());
25 | Encoder.writeString(outByteBuf, header.getMsgTime());
26 | }
27 |
28 | public Header deserialize(ByteBuf inByteBuf) throws Exception {
29 | long msgNum = Decoder.readLong(inByteBuf);
30 | Byte msgType = Decoder.readByte(inByteBuf);
31 | String msgTime = Decoder.readString(inByteBuf);
32 |
33 | Header header = new Header();
34 | header.setMsgNum(msgNum);
35 | header.setMsgType(DynamicMsgType.getMsgTypeEnum(msgType));
36 | header.setMsgTime(msgTime);
37 |
38 | return header;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/IBodySerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.dynamic.message.Body;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/7/29
9 | * @description
10 | */
11 |
12 |
13 | public interface IBodySerializer {
14 | public void serialize(ByteBuf outByteBuf, Body body) throws Exception;
15 |
16 | public T deserialize(ByteBuf inByteBuf) throws Exception;
17 | }
18 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/TailSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.core.CommonUtil;
5 | import org.lwl.netty.core.Decoder;
6 | import org.lwl.netty.core.Encoder;
7 | import org.lwl.netty.dynamic.message.Tail;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/7/29
12 | * @description
13 | */
14 |
15 |
16 | public class TailSerializer {
17 | private static final TailSerializer INSTANCE = new TailSerializer();
18 | private TailSerializer(){}
19 |
20 | public static TailSerializer getInstance() {
21 | return INSTANCE;
22 | }
23 |
24 | public void serialize(ByteBuf outByteBuf, Tail msg) throws Exception {
25 | int checkSum = CommonUtil.calCheckSum(outByteBuf, outByteBuf.writerIndex());
26 | Encoder.writeInt(outByteBuf, checkSum);
27 | }
28 |
29 | public Tail deserialize(ByteBuf inByteBuf) throws Exception {
30 | int checkSum = Decoder.readInt(inByteBuf);
31 |
32 | Tail tail = new Tail();
33 | tail.setCheckSum(checkSum);
34 |
35 | return tail;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/body/DefaultBodySerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.dynamic.codec.serialize.IBodySerializer;
5 | import org.lwl.netty.dynamic.message.Body;
6 |
7 | /**
8 | * @author thinking_fioa
9 | * @createTime 2018/7/29
10 | * @description
11 | */
12 |
13 |
14 | public final class DefaultBodySerializer implements IBodySerializer {
15 | private static final DefaultBodySerializer INSTANCE = new DefaultBodySerializer();
16 | private DefaultBodySerializer(){}
17 |
18 | public static DefaultBodySerializer getInstance() {
19 | return INSTANCE;
20 | }
21 |
22 | @Override
23 | public void serialize(ByteBuf outByteBuf, Body body) {
24 | }
25 |
26 | @Override
27 | public Body deserialize(ByteBuf inByteBuf) {
28 | return new Body();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/body/HtReqBodySerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.dynamic.codec.serialize.IBodySerializer;
5 | import org.lwl.netty.dynamic.message.Body;
6 | import org.lwl.netty.dynamic.message.body.HeartbeatReqBody;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/7/29
11 | * @description
12 | */
13 |
14 |
15 | public final class HtReqBodySerializer implements IBodySerializer {
16 |
17 | private static final HtReqBodySerializer INSTANCE = new HtReqBodySerializer();
18 | private HtReqBodySerializer(){}
19 |
20 | public static HtReqBodySerializer getInstance() {
21 | return INSTANCE;
22 | }
23 |
24 | @Override
25 | public void serialize(ByteBuf outByteBuf, Body body) {
26 |
27 | }
28 |
29 | @Override
30 | public HeartbeatReqBody deserialize(ByteBuf inByteBuf) {
31 | return new HeartbeatReqBody();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/body/HtRespBodySerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.dynamic.codec.serialize.IBodySerializer;
5 | import org.lwl.netty.dynamic.message.Body;
6 | import org.lwl.netty.dynamic.message.body.HeartbeatRespBody;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/7/29
11 | * @description
12 | */
13 |
14 |
15 | public final class HtRespBodySerializer implements IBodySerializer {
16 |
17 | private static final HtRespBodySerializer INSTANCE = new HtRespBodySerializer();
18 | private HtRespBodySerializer(){}
19 |
20 | public static HtRespBodySerializer getInstance() {
21 | return INSTANCE;
22 | }
23 |
24 | @Override
25 | public void serialize(ByteBuf outByteBuf, Body body) {
26 |
27 | }
28 |
29 | @Override
30 | public HeartbeatRespBody deserialize(ByteBuf inByteBuf) {
31 | return new HeartbeatRespBody();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/body/LoginReqBodySerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.core.Decoder;
5 | import org.lwl.netty.core.Encoder;
6 | import org.lwl.netty.dynamic.codec.serialize.IBodySerializer;
7 | import org.lwl.netty.dynamic.message.Body;
8 | import org.lwl.netty.dynamic.message.body.HeartbeatRespBody;
9 | import org.lwl.netty.dynamic.message.body.LoginReqBody;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/7/29
14 | * @description
15 | */
16 |
17 |
18 | public final class LoginReqBodySerializer implements IBodySerializer {
19 | private static final LoginReqBodySerializer INSTANCE = new LoginReqBodySerializer();
20 | private LoginReqBodySerializer(){}
21 |
22 | public static LoginReqBodySerializer getInstance() {
23 | return INSTANCE;
24 | }
25 |
26 | @Override
27 | public void serialize(ByteBuf outByteBuf, Body body) {
28 | LoginReqBody login = (LoginReqBody)body;
29 | Encoder.writeString(outByteBuf, login.getUserName());
30 | Encoder.writeString(outByteBuf, login.getPassword());
31 | }
32 |
33 | @Override
34 | public LoginReqBody deserialize(ByteBuf inByteBuf) {
35 | String userName = Decoder.readString(inByteBuf);
36 | String password = Decoder.readString(inByteBuf);
37 |
38 | LoginReqBody loginReqBody = new LoginReqBody();
39 | loginReqBody.setUserName(userName);
40 | loginReqBody.setPassword(password);
41 |
42 | return loginReqBody;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/body/LoginRespBodySerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.dynamic.codec.serialize.IBodySerializer;
5 | import org.lwl.netty.dynamic.message.Body;
6 | import org.lwl.netty.dynamic.message.body.LoginRespBody;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/7/29
11 | * @description
12 | */
13 |
14 |
15 | public final class LoginRespBodySerializer implements IBodySerializer {
16 | private static final LoginRespBodySerializer INSTANCE = new LoginRespBodySerializer();
17 | private LoginRespBodySerializer(){}
18 |
19 | public static LoginRespBodySerializer getInstance() {
20 | return INSTANCE;
21 | }
22 |
23 | @Override
24 | public void serialize(ByteBuf outByteBuf, Body body) {
25 |
26 | }
27 |
28 | @Override
29 | public LoginRespBody deserialize(ByteBuf inByteBuf) {
30 | return new LoginRespBody();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/body/LogoutBodySerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.dynamic.codec.serialize.IBodySerializer;
5 | import org.lwl.netty.dynamic.message.Body;
6 | import org.lwl.netty.dynamic.message.body.LogoutBody;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/7/29
11 | * @description
12 | */
13 |
14 |
15 | public class LogoutBodySerializer implements IBodySerializer {
16 |
17 | private static final LogoutBodySerializer INSTANCE = new LogoutBodySerializer();
18 | private LogoutBodySerializer(){}
19 |
20 | public static LogoutBodySerializer getInstance() {
21 | return INSTANCE;
22 | }
23 |
24 |
25 | @Override
26 | public void serialize(ByteBuf outByteBuf, Body body) {
27 |
28 | }
29 |
30 | @Override
31 | public LogoutBody deserialize(ByteBuf inByteBuf) {
32 | return new LogoutBody();
33 | }
34 | }
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/body/RandomCodeBodySerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.core.Decoder;
5 | import org.lwl.netty.core.Encoder;
6 | import org.lwl.netty.dynamic.codec.serialize.IBodySerializer;
7 | import org.lwl.netty.dynamic.message.Body;
8 | import org.lwl.netty.dynamic.message.body.RandomCodeBody;
9 |
10 | /**
11 | * @author thinking_fioa
12 | * @createTime 2018/7/29
13 | * @description
14 | */
15 |
16 |
17 | public final class RandomCodeBodySerializer implements IBodySerializer {
18 | private static final RandomCodeBodySerializer INSTANCE = new RandomCodeBodySerializer();
19 | private RandomCodeBodySerializer(){}
20 |
21 | public static RandomCodeBodySerializer getInstance() {
22 | return INSTANCE;
23 | }
24 |
25 | @Override
26 | public void serialize(ByteBuf outByteBuf, Body body) {
27 | RandomCodeBody randomCodeBody = (RandomCodeBody)body;
28 | Encoder.writeString(outByteBuf, randomCodeBody.getRandomCode());
29 | }
30 |
31 | @Override
32 | public RandomCodeBody deserialize(ByteBuf inByteBuf) {
33 | String randomCode = Decoder.readString(inByteBuf);
34 |
35 | RandomCodeBody randomCodeBody = new RandomCodeBody();
36 | randomCodeBody.setRandomCode(randomCode);
37 |
38 | return randomCodeBody;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/body/SslBodySerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.core.Decoder;
5 | import org.lwl.netty.core.Encoder;
6 | import org.lwl.netty.dynamic.codec.serialize.IBodySerializer;
7 | import org.lwl.netty.dynamic.message.Body;
8 | import org.lwl.netty.dynamic.message.body.RandomCodeBody;
9 | import org.lwl.netty.dynamic.message.body.SslBody;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/7/29
14 | * @description
15 | */
16 |
17 |
18 | public final class SslBodySerializer implements IBodySerializer {
19 | private static final SslBodySerializer INSTANCE = new SslBodySerializer();
20 | private SslBodySerializer(){}
21 |
22 | public static SslBodySerializer getInstance() {
23 | return INSTANCE;
24 | }
25 |
26 | @Override
27 | public void serialize(ByteBuf outByteBuf, Body body) {
28 | SslBody sslBody = (SslBody)body;
29 | Encoder.writeString(outByteBuf, sslBody.getSslVersion());
30 | }
31 |
32 | @Override
33 | public SslBody deserialize(ByteBuf inByteBuf) {
34 | String sslVersion = Decoder.readString(inByteBuf);
35 |
36 | SslBody sslBody = new SslBody();
37 | sslBody.setSslVersion(sslVersion);
38 |
39 | return sslBody;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/codec/serialize/body/SymEncryptionSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.codec.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import org.lwl.netty.core.Decoder;
5 | import org.lwl.netty.core.Encoder;
6 | import org.lwl.netty.dynamic.codec.serialize.IBodySerializer;
7 | import org.lwl.netty.dynamic.message.Body;
8 | import org.lwl.netty.dynamic.message.body.SymEncryption;
9 |
10 | /**
11 | * @author thinking_fioa
12 | * @createTime 2018/7/29
13 | * @description
14 | */
15 |
16 |
17 | public class SymEncryptionSerializer implements IBodySerializer {
18 | private static final SymEncryptionSerializer INSTANCE = new SymEncryptionSerializer();
19 |
20 | private SymEncryptionSerializer() {
21 | }
22 |
23 | public static SymEncryptionSerializer getInstance() {
24 | return INSTANCE;
25 | }
26 |
27 | @Override
28 | public void serialize(ByteBuf outByteBuf, Body body) {
29 | SymEncryption SymEncryption = (SymEncryption) body;
30 | Encoder.writeString(outByteBuf, SymEncryption.getSymEncryptionMethod());
31 | }
32 |
33 | @Override
34 | public SymEncryption deserialize(ByteBuf inByteBuf) {
35 | String symEncryptionMethod = Decoder.readString(inByteBuf);
36 |
37 | SymEncryption symEncryption = new SymEncryption();
38 | symEncryption.setSymEncryptionMethod(symEncryptionMethod);
39 |
40 | return symEncryption;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/Body.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message;
2 |
3 |
4 | import org.lwl.netty.dynamic.DynamicMsgType;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/5/9
9 | * @description
10 | */
11 |
12 |
13 | public class Body {
14 |
15 | public DynamicMsgType msgType() {
16 | return DynamicMsgType.UNKNOWN;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/DynamicMessage.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message;
2 |
3 | /**
4 | * @author thinking_fioa
5 | * @createTime 2018/4/21
6 | * @description 自定义消息格式消息
7 | */
8 |
9 |
10 | public class DynamicMessage {
11 |
12 | private Header header;
13 |
14 | private Body body;
15 |
16 | private Tail tail;
17 |
18 | private DynamicMessage(Header header, Body body, Tail tail) {
19 | this.header = header;
20 | this.body = body;
21 | this.tail = tail;
22 | }
23 |
24 | private DynamicMessage(Body body) {
25 | this.header = new Header();
26 | this.body = body;
27 | this.tail = new Tail();
28 | }
29 |
30 | public static DynamicMessage createMsgOfEncode(Body body) {
31 | return new DynamicMessage(body);
32 | }
33 |
34 | public static DynamicMessage createMsgOfDecode(Header header, Body body, Tail tail) {
35 | return new DynamicMessage(header, body, tail);
36 | }
37 |
38 | public Header getHeader() {
39 | return header;
40 | }
41 |
42 | public void setHeader(Header header) {
43 | this.header = header;
44 | }
45 |
46 | public Body getBody() {
47 | return body;
48 | }
49 |
50 | public void setBody(Body body) {
51 | this.body = body;
52 | }
53 |
54 | public Tail getTail() {
55 | return tail;
56 | }
57 |
58 | public void setTail(Tail tail) {
59 | this.tail = tail;
60 | }
61 |
62 | @Override
63 | public String toString() {
64 | return "DynamicMessage: " + header.toString() + body.toString() + tail.toString();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/Header.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message;
2 |
3 | import org.lwl.netty.dynamic.DynamicMsgType;
4 |
5 | import java.util.HashMap;
6 | import java.util.Map;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/4/21
11 | * @description 消息头
12 | */
13 |
14 |
15 | public class Header {
16 | /**
17 | * 发送消息数目
18 | */
19 | private long msgNum;
20 |
21 | /**
22 | * 消息类型,{@code DynamicMsgType}
23 | */
24 | private DynamicMsgType msgType;
25 |
26 | /**
27 | * 消息时间,格式:
28 | */
29 | private String msgTime;
30 |
31 | public long getMsgNum() {
32 | return msgNum;
33 | }
34 |
35 | public void setMsgNum(long msgNum) {
36 | this.msgNum = msgNum;
37 | }
38 |
39 | public DynamicMsgType getMsgType() {
40 | return msgType;
41 | }
42 |
43 | public void setMsgType(DynamicMsgType msgType) {
44 | this.msgType = msgType;
45 | }
46 |
47 | public String getMsgTime() {
48 | return msgTime;
49 | }
50 |
51 | public void setMsgTime(String msgTime) {
52 | this.msgTime = msgTime;
53 | }
54 |
55 | @Override
56 | public String toString() {
57 | StringBuilder sb = new StringBuilder();
58 | sb.append("Header [");
59 | sb.append("msgNum=").append(msgNum);
60 | sb.append(", msgType=").append(msgType).append("]");
61 |
62 | return sb.toString();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/Tail.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message;
2 |
3 | /**
4 | * @author thinking_fioa
5 | * @createTime 2018/4/21
6 | * @description 消息体尾部
7 | */
8 |
9 |
10 | public class Tail {
11 |
12 | private int checkSum;
13 |
14 | public int getCheckSum() {
15 | return checkSum;
16 | }
17 |
18 | public void setCheckSum(int checkSum) {
19 | this.checkSum = checkSum;
20 | }
21 |
22 | /**
23 | * 属性字节数
24 | * @return
25 | */
26 | public static int byteSize() {
27 | return 4;
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | StringBuilder sb = new StringBuilder();
33 | sb.append("Tail [");
34 | sb.append("checkSum=").append(checkSum).append("]");
35 |
36 | return sb.toString();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/body/HeartbeatReqBody.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message.body;
2 |
3 | import org.lwl.netty.dynamic.DynamicMsgType;
4 | import org.lwl.netty.dynamic.message.Body;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/5/26
9 | * @description 心跳数据
10 | */
11 |
12 |
13 | public class HeartbeatReqBody extends Body {
14 | // nothing
15 |
16 | @Override
17 | public DynamicMsgType msgType() {
18 | return DynamicMsgType.HEARTBEAT_REQ;
19 | }
20 |
21 | @Override
22 | public String toString(){
23 |
24 | return "HeartbeatReqBody []";
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/body/HeartbeatRespBody.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message.body;
2 |
3 | import org.lwl.netty.dynamic.DynamicMsgType;
4 | import org.lwl.netty.dynamic.message.Body;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/5/26
9 | * @description 心跳数据
10 | */
11 |
12 |
13 | public class HeartbeatRespBody extends Body {
14 | // nothing
15 |
16 | @Override
17 | public DynamicMsgType msgType() {
18 | return DynamicMsgType.HEARTBEAT_RESP;
19 | }
20 |
21 | @Override
22 | public String toString(){
23 |
24 | return "HeartbeatRespBody []";
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/body/LoginReqBody.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message.body;
2 |
3 | import org.lwl.netty.dynamic.DynamicMsgType;
4 | import org.lwl.netty.dynamic.message.Body;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/5/9
9 | * @description 登陆消息
10 | */
11 |
12 |
13 | public class LoginReqBody extends Body {
14 |
15 | private String userName;
16 | private String password;
17 |
18 | public String getUserName() {
19 | return userName;
20 | }
21 |
22 | public void setUserName(String userName) {
23 | this.userName = userName;
24 | }
25 |
26 | public String getPassword() {
27 | return password;
28 | }
29 |
30 | public void setPassword(String password) {
31 | this.password = password;
32 | }
33 |
34 | @Override
35 | public String toString() {
36 | StringBuilder sb = new StringBuilder();
37 | sb.append("LoginReqBody [");
38 | sb.append("userName=").append(userName);
39 | sb.append(", password=").append(password).append("]");
40 |
41 | return sb.toString();
42 | }
43 |
44 | @Override
45 | public DynamicMsgType msgType() {
46 | return DynamicMsgType.LOGIN_REQ;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/body/LoginRespBody.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message.body;
2 |
3 | import org.lwl.netty.dynamic.DynamicMsgType;
4 | import org.lwl.netty.dynamic.message.Body;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/5/9
9 | * @description 登陆消息
10 | */
11 |
12 |
13 | public class LoginRespBody extends Body {
14 |
15 | @Override
16 | public String toString() {
17 | StringBuilder sb = new StringBuilder();
18 | sb.append("LoginRespBody []");
19 | return sb.toString();
20 | }
21 |
22 | @Override
23 | public DynamicMsgType msgType() {
24 | return DynamicMsgType.LOGIN_RESP;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/body/LogoutBody.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message.body;
2 |
3 | import org.lwl.netty.dynamic.DynamicMsgType;
4 | import org.lwl.netty.dynamic.message.Body;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/7/29
9 | * @description
10 | */
11 |
12 |
13 | public class LogoutBody extends Body {
14 | @Override
15 | public DynamicMsgType msgType() {
16 | return DynamicMsgType.LOGOUT;
17 | }
18 |
19 | @Override
20 | public String toString() {
21 | StringBuilder sb = new StringBuilder();
22 | sb.append("LogoutBody []");
23 | return sb.toString();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/body/RandomCodeBody.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message.body;
2 |
3 | import org.lwl.netty.dynamic.DynamicMsgType;
4 | import org.lwl.netty.dynamic.message.Body;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/7/28
9 | * @description
10 | */
11 |
12 |
13 | public class RandomCodeBody extends Body{
14 |
15 | private String randomCode;
16 |
17 | public String getRandomCode() {
18 | return randomCode;
19 | }
20 |
21 | public void setRandomCode(String randomCode) {
22 | this.randomCode = randomCode;
23 | }
24 |
25 | @Override
26 | public String toString() {
27 | StringBuilder sb = new StringBuilder();
28 | sb.append("RandomCodeBody [");
29 | sb.append("randomCode=").append(randomCode).append("]");
30 |
31 | return sb.toString();
32 | }
33 |
34 | @Override
35 | public DynamicMsgType msgType() {
36 | return DynamicMsgType.RANDOM_CODE;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/body/SslBody.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message.body;
2 |
3 | import org.lwl.netty.dynamic.DynamicMsgType;
4 | import org.lwl.netty.dynamic.message.Body;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/7/28
9 | * @description
10 | */
11 |
12 |
13 | public class SslBody extends Body {
14 |
15 | /**
16 | * ssl的版本
17 | */
18 | private String sslVersion;
19 |
20 | public String getSslVersion() {
21 | return sslVersion;
22 | }
23 |
24 | public void setSslVersion(String sslVersion) {
25 | this.sslVersion = sslVersion;
26 | }
27 |
28 | @Override
29 | public String toString() {
30 | StringBuilder sb = new StringBuilder();
31 | sb.append("SslBody [");
32 | sb.append("sslVersion=").append(sslVersion).append("]");
33 |
34 | return sb.toString();
35 | }
36 |
37 | @Override
38 | public DynamicMsgType msgType() {
39 | return DynamicMsgType.SSL;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/message/body/SymEncryption.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.message.body;
2 |
3 | import org.lwl.netty.dynamic.DynamicMsgType;
4 | import org.lwl.netty.dynamic.message.Body;
5 |
6 | /**
7 | * @author thinking_fioa
8 | * @createTime 2018/7/28
9 | * @description
10 | */
11 |
12 |
13 | public class SymEncryption extends Body{
14 | /**
15 | * 对称加密方法
16 | */
17 | private String symEncryptionMethod;
18 |
19 | public String getSymEncryptionMethod() {
20 | return symEncryptionMethod;
21 | }
22 |
23 | public void setSymEncryptionMethod(String symEncryptionMethod) {
24 | this.symEncryptionMethod = symEncryptionMethod;
25 | }
26 |
27 | @Override
28 | public String toString() {
29 | StringBuilder sb = new StringBuilder();
30 | sb.append("SymEncryption [");
31 | sb.append("symEncryptionMethod=").append(symEncryptionMethod).append("]");
32 |
33 | return sb.toString();
34 | }
35 |
36 | @Override
37 | public DynamicMsgType msgType() {
38 | return DynamicMsgType.SYM_ENCRYPTION;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/server/handler/ExceptionHanlder.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.server.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/8/12
11 | * @description
12 | */
13 |
14 |
15 | public class ExceptionHanlder extends ChannelInboundHandlerAdapter{
16 | private static final Logger LOGGER = LogManager.getLogger(ExceptionHanlder.class);
17 |
18 | @Override
19 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
20 | throws Exception {
21 | LOGGER.error("happen unknown exception.", cause);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/server/handler/HeartbeatServerHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.server.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import io.netty.handler.timeout.IdleState;
6 | import io.netty.handler.timeout.IdleStateEvent;
7 | import org.apache.logging.log4j.LogManager;
8 | import org.apache.logging.log4j.Logger;
9 | import org.lwl.netty.dynamic.DynamicConfig;
10 | import org.lwl.netty.dynamic.DynamicMsgType;
11 | import org.lwl.netty.dynamic.message.DynamicMessage;
12 | import org.lwl.netty.dynamic.message.body.HeartbeatReqBody;
13 |
14 | /**
15 | * @author thinking_fioa
16 | * @createTime 2018/8/12
17 | * @description
18 | */
19 |
20 |
21 | public class HeartbeatServerHandler extends ChannelInboundHandlerAdapter{
22 | private static final Logger LOGGER = LogManager.getLogger(HeartbeatServerHandler.class);
23 | private int lossConnectTime = 0;
24 |
25 | @Override
26 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
27 | if(evt instanceof IdleStateEvent) {
28 | IdleStateEvent event = (IdleStateEvent)evt;
29 | if(event.state() == IdleState.READER_IDLE) {
30 | lossConnectTime ++;
31 | if(lossConnectTime > DynamicConfig.getHtMultiple()) {
32 | LOGGER.error("heartbeat timeout. close channel {}", ctx.channel().remoteAddress());
33 | ctx.close();
34 | return;
35 | }
36 | } else if(event.state() == IdleState.WRITER_IDLE) {
37 | LOGGER.warn("heartbeat timeout. lossCount {}", lossConnectTime);
38 | ctx.writeAndFlush(buildHtReqMsg());
39 | }
40 | } else {
41 | ctx.fireUserEventTriggered(evt);
42 | }
43 | }
44 |
45 | @Override
46 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
47 | DynamicMessage message = (DynamicMessage) msg;
48 | final DynamicMsgType msgType = message.getHeader().getMsgType();
49 | lossConnectTime = 0;
50 | if(DynamicMsgType.HEARTBEAT_RESP.equals(msgType)) {
51 | LOGGER.debug("receive heartbeat resp");
52 | return;
53 | } else {
54 | ctx.fireChannelRead(msg);
55 | }
56 | }
57 |
58 | private DynamicMessage buildHtReqMsg() {
59 | HeartbeatReqBody htReqBody = new HeartbeatReqBody();
60 |
61 | return DynamicMessage.createMsgOfEncode(htReqBody);
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/server/handler/LoginRespHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.server.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.dynamic.DynamicConfig;
8 | import org.lwl.netty.dynamic.DynamicMsgType;
9 | import org.lwl.netty.dynamic.message.DynamicMessage;
10 | import org.lwl.netty.dynamic.message.body.LoginReqBody;
11 | import org.lwl.netty.dynamic.message.body.LoginRespBody;
12 |
13 |
14 | /**
15 | * @author thinking_fioa
16 | * @createTime 2018/8/12
17 | * @description
18 | */
19 |
20 |
21 | public class LoginRespHandler extends ChannelInboundHandlerAdapter {
22 | private static final Logger LOGGER = LogManager.getLogger(LoginRespHandler.class);
23 |
24 | private final String USERNAME = DynamicConfig.getUserName();
25 | private final String PASSWD = DynamicConfig.getPasswd();
26 |
27 | @Override
28 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
29 | DynamicMessage message = (DynamicMessage) msg;
30 | final DynamicMsgType msgType = message.getHeader().getMsgType();
31 | if(DynamicMsgType.LOGIN_REQ.equals(msgType)) {
32 | LOGGER.info("receive login req.");
33 | LoginReqBody reqBody = (LoginReqBody)message.getBody();
34 | if(checkPermission(reqBody)) {
35 | LOGGER.info("user check pass. login resp sent.");
36 | ctx.channel().writeAndFlush(buildLoginResp());
37 | }
38 | } else {
39 | ctx.fireChannelRead(msg);
40 | }
41 | }
42 |
43 | private boolean checkPermission(LoginReqBody reqBody) {
44 | final String userName = reqBody.getUserName();
45 | final String passwd = reqBody.getPassword();
46 |
47 | return USERNAME.equals(userName) && PASSWD.equals(passwd);
48 | }
49 |
50 | private DynamicMessage buildLoginResp() {
51 | LoginRespBody respBody = new LoginRespBody();
52 |
53 | return DynamicMessage.createMsgOfEncode(respBody);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/server/handler/RandomCodeServerHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.server.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.dynamic.DynamicMsgType;
8 | import org.lwl.netty.dynamic.message.DynamicMessage;
9 | import org.lwl.netty.dynamic.message.body.RandomCodeBody;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/8/13
14 | * @description
15 | */
16 |
17 |
18 | public class RandomCodeServerHandler extends ChannelInboundHandlerAdapter {
19 | private static final Logger LOGGER = LogManager.getLogger(RandomCodeServerHandler.class);
20 |
21 | @Override
22 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
23 | DynamicMessage message = (DynamicMessage) msg;
24 | final DynamicMsgType msgType = message.getHeader().getMsgType();
25 | if(DynamicMsgType.RANDOM_CODE.equals(msgType)) {
26 | LOGGER.info("receive randomCode req. accomplish ssl process");
27 | RandomCodeBody randomCodeBody = (RandomCodeBody)message.getBody();
28 | ctx.channel().writeAndFlush(buildSslBody(randomCodeBody.getRandomCode()));
29 | } else {
30 | ctx.fireChannelRead(msg);
31 | }
32 | }
33 |
34 | private DynamicMessage buildSslBody(String randomCode) {
35 | RandomCodeBody randomCodeBody = new RandomCodeBody();
36 | randomCodeBody.setRandomCode(randomCode);
37 |
38 | return DynamicMessage.createMsgOfEncode(randomCodeBody);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/server/handler/SslServerHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.server.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.dynamic.DynamicMsgType;
8 | import org.lwl.netty.dynamic.message.DynamicMessage;
9 | import org.lwl.netty.dynamic.message.body.SslBody;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/8/12
14 | * @description
15 | */
16 |
17 |
18 | public class SslServerHandler extends ChannelInboundHandlerAdapter {
19 | private static final Logger LOGGER = LogManager.getLogger(SslServerHandler.class);
20 |
21 | @Override
22 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
23 | DynamicMessage message = (DynamicMessage) msg;
24 | final DynamicMsgType msgType = message.getHeader().getMsgType();
25 | if(DynamicMsgType.SSL.equals(msgType)) {
26 | LOGGER.info("receive ssl req.");
27 | SslBody sslBody = (SslBody)message.getBody();
28 | ctx.channel().writeAndFlush(buildSslBody(sslBody.getSslVersion()));
29 | } else {
30 | ctx.fireChannelRead(msg);
31 | }
32 | }
33 |
34 | private DynamicMessage buildSslBody(String version) {
35 | SslBody sslBody = new SslBody();
36 | sslBody.setSslVersion(version);
37 |
38 | return DynamicMessage.createMsgOfEncode(sslBody);
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/dynamic/server/handler/SymEncryptionServerHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.dynamic.server.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.dynamic.DynamicMsgType;
8 | import org.lwl.netty.dynamic.message.DynamicMessage;
9 | import org.lwl.netty.dynamic.message.body.SymEncryption;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/8/12
14 | * @description
15 | */
16 |
17 |
18 | public class SymEncryptionServerHandler extends ChannelInboundHandlerAdapter {
19 | private static final Logger LOGGER = LogManager.getLogger(SymEncryptionServerHandler.class);
20 |
21 | @Override
22 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
23 | DynamicMessage message = (DynamicMessage) msg;
24 | final DynamicMsgType msgType = message.getHeader().getMsgType();
25 | if(DynamicMsgType.SYM_ENCRYPTION.equals(msgType)) {
26 | LOGGER.info("receive symEncryption req.");
27 | SymEncryption symBody = (SymEncryption)message.getBody();
28 | ctx.channel().writeAndFlush(buildSslBody(symBody.getSymEncryptionMethod()));
29 | } else {
30 | ctx.fireChannelRead(msg);
31 | }
32 | }
33 |
34 | private DynamicMessage buildSslBody(String symEncryptionMethod) {
35 | SymEncryption symBody = new SymEncryption();
36 | symBody.setSymEncryptionMethod(symEncryptionMethod);
37 |
38 | return DynamicMessage.createMsgOfEncode(symBody);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/udp/Test.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.udp;
2 |
3 | /**
4 | * @author thinking_fioa
5 | * @createTime 2018/7/22
6 | * @description
7 | */
8 |
9 |
10 | public class Test {
11 | }
12 |
--------------------------------------------------------------------------------
/netty-practice/src/main/java/org/lwl/netty/util/Test.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.util;
2 |
3 | /**
4 | * @author thinking_fioa
5 | * @createTime 2018/7/28
6 | * @description
7 | */
8 |
9 |
10 | public class Test {
11 | }
12 |
--------------------------------------------------------------------------------
/netty-private-protocol/docs/pics/lengthField/lengthField-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-private-protocol/docs/pics/lengthField/lengthField-1.png
--------------------------------------------------------------------------------
/netty-private-protocol/docs/pics/lengthField/lengthField-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-private-protocol/docs/pics/lengthField/lengthField-2.png
--------------------------------------------------------------------------------
/netty-private-protocol/docs/pics/lengthField/lengthField-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-private-protocol/docs/pics/lengthField/lengthField-3.png
--------------------------------------------------------------------------------
/netty-private-protocol/docs/pics/lengthField/lengthField-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-private-protocol/docs/pics/lengthField/lengthField-4.png
--------------------------------------------------------------------------------
/netty-private-protocol/docs/pics/lengthField/lengthField-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-private-protocol/docs/pics/lengthField/lengthField-5.png
--------------------------------------------------------------------------------
/netty-private-protocol/docs/pics/lengthField/lengthField-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-private-protocol/docs/pics/lengthField/lengthField-6.png
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/bin/buildProto.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | protoc -I=../proto/ --java_out=../../java/ Body.proto
4 | protoc -I=../proto/ --java_out=../../java/ Header.proto
5 | protoc -I=../proto/ --java_out=../../java/ HeartbeatReqBody.proto
6 | protoc -I=../proto/ --java_out=../../java/ HeartbeatRespBody.proto
7 | protoc -I=../proto/ --java_out=../../java/ LoginReqBody.proto
8 | protoc -I=../proto/ --java_out=../../java/ LoginRespBody.proto
9 | protoc -I=../proto/ --java_out=../../java/ LogoutBody.proto
10 | protoc -I=../proto/ --java_out=../../java/ ProtocolDataBody.proto
11 | protoc -I=../proto/ --java_out=../../java/ ProtocolSubBody.proto
12 | protoc -I=../proto/ --java_out=../../java/ Tail.proto
13 | protoc -I=../proto/ --java_out=../../java/ ProtocolMessage.proto
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/data/entertainment.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-private-protocol/src/main/Resources/data/entertainment.txt
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/data/news.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-private-protocol/src/main/Resources/data/news.txt
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/data/sports.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thinkingfioa/netty-learning/739323d31ff2a81879bc0e624606f5562a753541/netty-private-protocol/src/main/Resources/data/sports.txt
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/netty-private-protocol.properties:
--------------------------------------------------------------------------------
1 |
2 | ## netty server port
3 | ip=127.0.0.1
4 | port=9080
5 |
6 | ## unit: s
7 | heartbeat.interval=5
8 |
9 | ## login user/passwd
10 | username=thinkingfioa
11 | password=123456
12 |
13 | ### UTF-8/GBK
14 | charset.format=UTF-8
15 |
16 | ### transport pkg max size, unit: B
17 | pkg.max.len=4096
18 |
19 | ### codec. 1 - Marshalling; 2 - Kryo; 3 - Protobuf; 4 - Thrift; 5 - Avro
20 | message.codec=2
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/proto/Body.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_package = "org.lwl.netty.message.protobuf";
4 | option java_outer_classname = "Body";
5 |
6 | message BodyP {
7 |
8 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/proto/Header.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_package = "org.lwl.netty.message.protobuf";
4 | option java_outer_classname = "Header";
5 |
6 | message HeaderP {
7 | int64 msgNum=1;
8 |
9 | MessageTypeEnum msgType=2;
10 |
11 | string msgTime=3;
12 |
13 | int32 flag = 4;
14 |
15 | int32 oneByte = 5;
16 |
17 | map attachment=6;
18 | }
19 |
20 | enum MessageTypeEnum {
21 | UNKNOWN=0;
22 | LOGIN_REQ=1;
23 | LOGIN_RESP=2;
24 | LOGOUT=3;
25 | HEARTBEAT_REQ=4;
26 | HEARTBEAT_RESP=5;
27 | PROTOCOL_SUB=6;
28 | PROTOCOL_DATA=7;
29 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/proto/HeartbeatReqBody.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_package = "org.lwl.netty.message.protobuf";
4 | option java_outer_classname = "HeartbeatReqBody";
5 |
6 | message HeartbeatReqBodyP {
7 |
8 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/proto/HeartbeatRespBody.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_package = "org.lwl.netty.message.protobuf";
4 | option java_outer_classname = "HeartbeatRespBody";
5 |
6 | message HeartbeatRespBodyP {
7 |
8 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/proto/LoginReqBody.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_package = "org.lwl.netty.message.protobuf";
4 | option java_outer_classname = "LoginReqBody";
5 |
6 | message LoginReqBodyP {
7 | string userName = 1;
8 | string password = 2;
9 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/proto/LoginRespBody.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_package = "org.lwl.netty.message.protobuf";
4 | option java_outer_classname = "LoginRespBody";
5 |
6 | message LoginRespBodyP {
7 |
8 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/proto/LogoutBody.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_package = "org.lwl.netty.message.protobuf";
4 | option java_outer_classname = "LogoutBody";
5 |
6 | message LogoutBodyP {
7 |
8 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/proto/ProtocolDataBody.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_package = "org.lwl.netty.message.protobuf";
4 | option java_outer_classname = "ProtocolDataBody";
5 |
6 | message ProtocolDataBodyP {
7 | sint64 pkgSum = 1;
8 | sint64 pkgSequenceNum = 2;
9 | int32 contentLen = 3;
10 | bytes content = 4;
11 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/proto/ProtocolMessage.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_package = "org.lwl.netty.message.protobuf";
4 | option java_outer_classname = "ProtocolMessage";
5 |
6 | import "Header.proto";
7 | import "Body.proto";
8 | import "HeartbeatReqBody.proto";
9 | import "HeartbeatRespBody.proto";
10 | import "LoginReqBody.proto";
11 | import "LoginRespBody.proto";
12 | import "LogoutBody.proto";
13 | import "ProtocolDataBody.proto";
14 | import "ProtocolSubBody.proto";
15 | import "Tail.proto";
16 |
17 | message ProtocolMessageP {
18 | HeaderP header = 1;
19 | oneof body {
20 | BodyP bodyMsg = 2;
21 | HeartbeatReqBodyP heartbeatReqBody = 3;
22 | HeartbeatRespBodyP heartbeatRespBody = 4;
23 | LoginReqBodyP loginReqBody = 5;
24 | LoginRespBodyP loginRespBody = 6;
25 | LogoutBodyP logoutBody = 7;
26 | ProtocolDataBodyP protocolDataBody = 8;
27 | ProtocolSubBodyP protocolSubBody = 9;
28 | }
29 | TailP tail = 10;
30 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/proto/ProtocolSubBody.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_package = "org.lwl.netty.message.protobuf";
4 | option java_outer_classname = "ProtocolSubBody";
5 |
6 | message ProtocolSubBodyP {
7 | repeated ProtocolDataType dataTypeList = 1;
8 | }
9 |
10 | enum ProtocolDataType {
11 | DEFAULT = 0;
12 | NEWS = 1;
13 | SPORTS = 2;
14 | ENTERTAINMENT = 3;
15 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/Resources/proto/Tail.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_package = "org.lwl.netty.message.protobuf";
4 | option java_outer_classname = "Tail";
5 |
6 | message TailP {
7 | int32 checkSum=1;
8 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/NettyServerAndClientStart.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty;
2 |
3 | import org.lwl.netty.client.NettyClient;
4 | import org.lwl.netty.client.NettyClientAdapter;
5 | import org.lwl.netty.config.ProtocolConfig;
6 | import org.lwl.netty.server.NettyServer;
7 |
8 | import java.io.IOException;
9 |
10 | /**
11 | * @author thinking_fioa
12 | * @createTime 2018/4/22
13 | * @description 分别以线程的方式启动NettyClient和NettyServer
14 | */
15 |
16 |
17 | public class NettyServerAndClientStart {
18 |
19 | public static void main(String [] args) throws IOException, InterruptedException {
20 | ProtocolConfig.init();
21 | // 用线程启动
22 | // 启动 Server
23 | new Thread(() -> {
24 | new NettyServer().start();
25 | }).start();
26 |
27 | Thread.sleep(60000);
28 |
29 | new Thread(() -> {
30 | new NettyClientAdapter(new NettyClient()).start();
31 | }).start();
32 | }
33 | }
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/ProtobufServerAndClientStart.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty;
2 |
3 | import org.lwl.netty.client.NettyClientAdapter;
4 | import org.lwl.netty.client.ProtobufNettyClient;
5 | import org.lwl.netty.config.ProtocolConfig;
6 | import org.lwl.netty.server.NettyServer;
7 | import org.lwl.netty.server.ProtobufNettyServer;
8 |
9 | import java.io.IOException;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/7/8
14 | * @description 由于Protobuf使用的消息{@link org.lwl.netty.message.protobuf}非常特殊,所以,所有的传输机制
15 | * 都与编码方式:Marshalling和Kryo不同。单独一套。
16 | */
17 |
18 | public class ProtobufServerAndClientStart {
19 | public static void main(String [] args) throws IOException {
20 | ProtocolConfig.init();
21 | new Thread(() -> {
22 | new ProtobufNettyServer().start();
23 | }).start();
24 |
25 | new Thread(() -> {
26 | new NettyClientAdapter(new ProtobufNettyClient()).start();
27 | }).start();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/client/NettyClientAdapter.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.client;
2 |
3 | import io.netty.channel.ChannelFuture;
4 | import io.netty.channel.ChannelFutureListener;
5 | import io.netty.channel.EventLoopGroup;
6 | import io.netty.channel.nio.NioEventLoopGroup;
7 | import org.apache.logging.log4j.LogManager;
8 | import org.apache.logging.log4j.Logger;
9 | import org.lwl.netty.config.ProtocolConfig;
10 | import org.lwl.netty.server.NettyServer;
11 | import org.lwl.netty.util.concurrent.CustomThreadFactory;
12 |
13 | /**
14 | * @author thinking_fioa
15 | * @createTime 2018/5/12
16 | * @description NettyClient适配器,可以控制重连机制。另一个项目可以见到链路切换
17 | */
18 |
19 | public class NettyClientAdapter {
20 | private static final Logger LOGGER = LogManager.getLogger(NettyClientAdapter.class);
21 |
22 | private static final CustomThreadFactory THREAD_FACTORY = new CustomThreadFactory("ClientEventLoop", false);
23 |
24 | private final String ip;
25 | private final int port;
26 | private final EventLoopGroup clientGroup;
27 | private final NettyClient client;
28 |
29 | public NettyClientAdapter(NettyClient client) {
30 | this.ip = ProtocolConfig.getIp();
31 | this.port = ProtocolConfig.getPort();
32 | clientGroup = new NioEventLoopGroup(1, THREAD_FACTORY);
33 | this.client = client;
34 | }
35 |
36 | public void start() {
37 | connection(ip, port);
38 | }
39 |
40 | public void quit() {
41 | if(null != clientGroup) {
42 | clientGroup.shutdownGracefully();
43 | }
44 | }
45 |
46 | public void reconnect() {
47 |
48 | new Thread( () -> {
49 | connection(ip, port);
50 | }
51 | ).start();
52 | }
53 |
54 | private void connection(final String ip, final int port) {
55 | try {
56 | ChannelFuture cf = client.connect(clientGroup, ip, port);
57 | cf.addListener(new ChannelFutureListener() {
58 | @Override
59 | public void operationComplete(ChannelFuture future) throws Exception {
60 | if(future.isSuccess()) {
61 | LOGGER.info("client connect success. ip:{}, port:{}", ip, port);
62 | } else {
63 | LOGGER.error("connect fail.", future.cause());
64 | reconnect();
65 | }
66 | }
67 | });
68 | } catch (Exception e) {
69 | reconnect();
70 | }
71 |
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/client/ProtobufNettyClient.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.client;
2 |
3 | import io.netty.bootstrap.Bootstrap;
4 | import io.netty.channel.ChannelInitializer;
5 | import io.netty.channel.socket.SocketChannel;
6 | import io.netty.handler.codec.protobuf.ProtobufDecoder;
7 | import io.netty.handler.codec.protobuf.ProtobufEncoder;
8 | import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
9 | import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
10 | import io.netty.handler.timeout.IdleStateHandler;
11 | import org.lwl.netty.client.handler.ClientExceptionHandler;
12 | import org.lwl.netty.client.handler.protobuf.HeartbeatClientHandler;
13 | import org.lwl.netty.client.handler.protobuf.LoginReqHandler;
14 | import org.lwl.netty.codec.other.ProtocolDataDecoder;
15 | import org.lwl.netty.codec.other.ProtocolDataEncoder;
16 | import org.lwl.netty.config.ProtocolConfig;
17 |
18 | import java.util.concurrent.TimeUnit;
19 |
20 | /**
21 | * @author thinking_fioa
22 | * @createTime 2018/7/8
23 | * @description
24 | */
25 |
26 |
27 | public class ProtobufNettyClient extends NettyClient {
28 |
29 | @Override
30 | public void initChannel0(Bootstrap bootstrap) {
31 | bootstrap.handler(new ProtobufChildChannelHandler());
32 | }
33 |
34 | private static class ProtobufChildChannelHandler extends ChannelInitializer {
35 | @Override
36 | protected void initChannel(SocketChannel ch) throws Exception {
37 | // ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
38 | ch.pipeline().addLast(new ProtobufVarint32FrameDecoder());
39 | ch.pipeline().addLast(new ProtobufDecoder(org.lwl.netty.message.protobuf.ProtocolMessage.ProtocolMessageP.getDefaultInstance()));
40 | ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
41 | ch.pipeline().addLast(new ProtobufEncoder());
42 | ch.pipeline().addLast(new LoginReqHandler());
43 | ch.pipeline().addLast(new IdleStateHandler(ProtocolConfig.getHeartbeatInterval(), ProtocolConfig.getHeartbeatInterval(), 0, TimeUnit.SECONDS));
44 | ch.pipeline().addLast(new HeartbeatClientHandler());
45 | // ch.pipeline().addLast(new ProtocolMsgSubHandler());
46 | ch.pipeline().addLast(new ClientExceptionHandler());
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/client/handler/ClientExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.client.handler;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/5/26
11 | * @description 处理客户端异常输出
12 | */
13 |
14 |
15 | public class ClientExceptionHandler extends ChannelInboundHandlerAdapter {
16 |
17 | private static final Logger LOGGER = LogManager.getLogger(ClientExceptionHandler.class);
18 |
19 | @Override
20 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
21 | LOGGER.error("Client Handler happen exception.", cause);
22 | }
23 |
24 | @Override
25 | public void channelInactive(ChannelHandlerContext ctx) throws Exception {
26 | LOGGER.error("client close channel.");
27 | ctx.close();
28 | }
29 |
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/client/handler/other/LoginReqHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.client.handler.other;
2 |
3 | import io.netty.channel.ChannelHandler;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.channel.ChannelInboundHandlerAdapter;
6 | import org.apache.logging.log4j.LogManager;
7 | import org.apache.logging.log4j.Logger;
8 | import org.lwl.netty.config.ProtocolConfig;
9 | import org.lwl.netty.constant.MessageTypeEnum;
10 | import org.lwl.netty.message.ProtocolMessage;
11 | import org.lwl.netty.message.body.LoginReqBody;
12 |
13 | /**
14 | * @author thinking_fioa
15 | * @createTime 2018/5/24
16 | * @description 登陆请求
17 | */
18 |
19 | @ChannelHandler.Sharable
20 | public class LoginReqHandler extends ChannelInboundHandlerAdapter {
21 | private static final Logger LOGGER = LogManager.getLogger(LoginReqHandler.class);
22 |
23 | private static final String USERNAME = ProtocolConfig.getUserName();
24 | private static final String PASSWORD = ProtocolConfig.getPassword();
25 |
26 | @Override
27 | public void channelActive(ChannelHandlerContext ctx) {
28 | ProtocolMessage loginMsg = buildLoginReqMsg();
29 | LOGGER.info("channel active. login req sent.");
30 | ctx.writeAndFlush(loginMsg);
31 | }
32 |
33 | @Override
34 | public void channelRead(ChannelHandlerContext ctx, Object msg) {
35 | ProtocolMessage message = (ProtocolMessage) msg;
36 | final MessageTypeEnum msgType = message.getHeader().getMsgType();
37 | if(MessageTypeEnum.LOGIN_RESP.equals(msgType)) {
38 | LOGGER.info("receive login resp.");
39 | } else {
40 | ctx.fireChannelRead(msg);
41 | }
42 | }
43 |
44 | private ProtocolMessage buildLoginReqMsg() {
45 | LoginReqBody loginReqBody = new LoginReqBody();
46 | loginReqBody.setUserName(USERNAME);
47 | loginReqBody.setPassword(PASSWORD);
48 |
49 | return ProtocolMessage.createMsgOfEncode(loginReqBody);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/client/handler/other/ProtocolMsgSubHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.client.handler.other;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.constant.ProtocolDataType;
8 | import org.lwl.netty.message.ProtocolMessage;
9 | import org.lwl.netty.message.body.ProtocolSubBody;
10 |
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | /**
15 | * @author thinking_fioa
16 | * @createTime 2018/5/24
17 | * @description Protocol消息订阅和接收服务
18 | */
19 |
20 | public class ProtocolMsgSubHandler extends ChannelInboundHandlerAdapter {
21 | private static final Logger LOGGER = LogManager.getLogger(ProtocolMsgSubHandler.class);
22 |
23 | @Override
24 | public void channelActive(ChannelHandlerContext ctx) {
25 | ProtocolMessage ptclSubMsg = buildPtclSubMsg();
26 | LOGGER.info("MsgSub active. protocol msg sub sent");
27 | ctx.writeAndFlush(ptclSubMsg);
28 | }
29 |
30 | private ProtocolMessage buildPtclSubMsg() {
31 | ProtocolSubBody subBody = new ProtocolSubBody();
32 | List dataTypeList = new ArrayList();
33 | dataTypeList.add(ProtocolDataType.NEWS);
34 | dataTypeList.add(ProtocolDataType.SPORTS);
35 | dataTypeList.add(ProtocolDataType.ENTERTAINMENT);
36 |
37 | return ProtocolMessage.createMsgOfEncode(subBody);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/client/handler/protobuf/ProtobufClientCodecHelper.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.client.handler.protobuf;
2 |
3 | import org.lwl.netty.message.protobuf.Header;
4 | import org.lwl.netty.message.protobuf.ProtocolMessage;
5 | import org.lwl.netty.message.protobuf.Tail;
6 | import org.lwl.netty.util.CommonUtil;
7 |
8 | import java.util.HashMap;
9 | import java.util.Map;
10 | import java.util.concurrent.atomic.AtomicLong;
11 |
12 | /**
13 | * @author thinking_fioa
14 | * @createTime 2018/7/11
15 | * @description 帮助Protobuf编码和解码工具类
16 | */
17 |
18 | final class ProtobufClientCodecHelper {
19 |
20 | private static final AtomicLong MSG_NUM = new AtomicLong(0);
21 |
22 | private ProtobufClientCodecHelper() {
23 | throw new IllegalAccessError("can not use constructor.");
24 | }
25 |
26 | public static Header.HeaderP.Builder generateHeaderBuilder(Header.MessageTypeEnum msgType) {
27 | Header.HeaderP.Builder headerBuilder = Header.HeaderP.newBuilder();
28 |
29 | headerBuilder.setMsgNum(MSG_NUM.get());
30 | headerBuilder.setMsgType(msgType);
31 | headerBuilder.setMsgTime(CommonUtil.nowTime());
32 | // 下面的值,随机填。主要目的是证明协议支持多种类型格式
33 | headerBuilder.setFlag(2);
34 | headerBuilder.setOneByte(3);
35 | Map attachment = new HashMap<>();
36 | attachment.put("name", "luweilin");
37 | attachment.put("age", "20");
38 | headerBuilder.putAllAttachment(attachment);
39 |
40 | return headerBuilder;
41 | }
42 |
43 | public static Tail.TailP.Builder generateTailBuilder(ProtocolMessage.ProtocolMessageP.Builder msgBuilder) {
44 | byte[] bytes = msgBuilder.build().toByteArray();
45 | int checkSum = CommonUtil.calCheckSum(bytes);
46 | Tail.TailP.Builder tailBuilder = Tail.TailP.newBuilder();
47 | tailBuilder.setCheckSum(checkSum);
48 |
49 | return tailBuilder;
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/client/handler/protobuf/ProtocolMsgSubHandler.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.client.handler.protobuf;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.lwl.netty.message.protobuf.*;
8 | import org.lwl.netty.message.protobuf.ProtocolSubBody.ProtocolDataType;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | /**
14 | * @author thinking_fioa
15 | * @createTime 2018/7/11
16 | * @description
17 | */
18 |
19 |
20 | public class ProtocolMsgSubHandler extends ChannelInboundHandlerAdapter {
21 | private static final Logger LOGGER = LogManager.getLogger(ProtocolMsgSubHandler.class);
22 |
23 | @Override
24 | public void channelActive(ChannelHandlerContext ctx) {
25 | ProtocolMessage.ProtocolMessageP msg = buildPtclSubMsg();
26 | LOGGER.info("MsgSub active. protocol msg sub sent.");
27 | ctx.writeAndFlush(msg);
28 | }
29 |
30 | private ProtocolMessage.ProtocolMessageP buildPtclSubMsg() {
31 | ProtocolMessage.ProtocolMessageP.Builder msgBuilder= ProtocolMessage.ProtocolMessageP.newBuilder();
32 | // Header
33 | Header.HeaderP.Builder headerBuilder = ProtobufClientCodecHelper.generateHeaderBuilder(Header.MessageTypeEnum.PROTOCOL_SUB);
34 | msgBuilder.setHeader(headerBuilder);
35 | // Body
36 | ProtocolSubBody.ProtocolSubBodyP.Builder subBuilder = ProtocolSubBody.ProtocolSubBodyP.newBuilder();
37 | List dataTypeList = new ArrayList<>();
38 | dataTypeList.add(ProtocolDataType.NEWS);
39 | dataTypeList.add(ProtocolDataType.SPORTS);
40 | dataTypeList.add(ProtocolDataType.ENTERTAINMENT);
41 | subBuilder.addAllDataTypeList(dataTypeList);
42 | // Tail
43 | Tail.TailP.Builder tailBuilder = ProtobufClientCodecHelper.generateTailBuilder(msgBuilder);
44 | msgBuilder.setTail(tailBuilder);
45 |
46 | return msgBuilder.build();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/IMessageCodecUtil.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 |
6 | import java.io.IOException;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/5/9
11 | * @description
12 | */
13 |
14 |
15 | public interface IMessageCodecUtil {
16 |
17 | void encode(ChannelHandlerContext ctx, ByteBuf outByteBuf, T object) throws Exception;
18 |
19 | T decode(ChannelHandlerContext ctx, ByteBuf inByteBuf) throws Exception;
20 | }
21 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/ProtocolDataDecoder.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.handler.codec.EncoderException;
6 | import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
7 | import org.apache.logging.log4j.LogManager;
8 | import org.apache.logging.log4j.Logger;
9 | import org.lwl.netty.constant.ProtocolConstant;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/4/26
14 | * @description 解码器
15 | */
16 |
17 |
18 | public class ProtocolDataDecoder extends LengthFieldBasedFrameDecoder {
19 | private static final Logger LOGGER = LogManager.getLogger(ProtocolDataDecoder.class);
20 |
21 | private static final int MAX_FRAMELENGTH = ProtocolConstant.getMaxFramelength();
22 | private static final int LENGTH_FIELD_OFFSET = ProtocolConstant.getLengthFieldOffset();
23 | private static final int LENGTHFIELD_LENGTH = ProtocolConstant.getLengthfieldLength();
24 | private static final int LENGTH_ADJUSTMENT = ProtocolConstant.getLengthAdjustment();
25 | private static final int INITIAL_BYTES_TO_STRIP = ProtocolConstant.getInitialBytesToStrip();
26 |
27 | private IMessageCodecUtil codecUtil;
28 |
29 | public ProtocolDataDecoder() {
30 | super(MAX_FRAMELENGTH, LENGTH_FIELD_OFFSET, LENGTHFIELD_LENGTH, LENGTH_ADJUSTMENT, INITIAL_BYTES_TO_STRIP);
31 | this.codecUtil = MessageCodecUtilFactory.getCodecUtil();
32 | }
33 |
34 | @Override
35 | public Object decode(ChannelHandlerContext ctx, ByteBuf inByteBuf) throws Exception{
36 | ByteBuf frame = null;
37 | try {
38 | frame = (ByteBuf) super.decode(ctx, inByteBuf);
39 | if(null == frame) {
40 | return null;
41 | }
42 |
43 | return codecUtil.decode(ctx, frame);
44 |
45 | } catch (Throwable cause) {
46 | LOGGER.error("Decode error.", cause);
47 | throw new EncoderException("Decode error.");
48 | } finally {
49 | if(null != frame) {
50 | frame.release();
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/ProtocolDataEncoder.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.handler.codec.MessageToByteEncoder;
6 | import org.apache.logging.log4j.LogManager;
7 | import org.apache.logging.log4j.Logger;
8 | import org.lwl.netty.message.Header;
9 | import org.lwl.netty.message.ProtocolMessage;
10 | import org.lwl.netty.util.CommonUtil;
11 |
12 | import java.util.HashMap;
13 | import java.util.Map;
14 |
15 | /**
16 | * @author thinking_fioa
17 | * @createTime 2018/4/26
18 | * @description 编码器
19 | */
20 |
21 |
22 | public class ProtocolDataEncoder extends MessageToByteEncoder {
23 | private static final Logger LOGGER = LogManager.getLogger(ProtocolDataEncoder.class);
24 |
25 | private long msgNum = 1;
26 |
27 | private IMessageCodecUtil codecUtil;
28 |
29 | public ProtocolDataEncoder() {
30 | this.codecUtil = MessageCodecUtilFactory.getCodecUtil();
31 | }
32 |
33 | @Override
34 | protected void encode(ChannelHandlerContext ctx, ProtocolMessage protocolMessage, ByteBuf outByteBuf) throws Exception {
35 | if(null == protocolMessage || null == protocolMessage.getBody()) {
36 | LOGGER.error("protocolMessage is null. refuse encode");
37 |
38 | return;
39 | }
40 | try {
41 | // 填写头协议
42 | fillInHeader(protocolMessage);
43 |
44 | codecUtil.encode(ctx, outByteBuf, protocolMessage);
45 | LOGGER.info("--> encode msgType:{}, msLen: {}", protocolMessage.getHeader().getMsgType(), outByteBuf.writerIndex());
46 | } catch(Throwable cause) {
47 | LOGGER.error("Encode error.", cause);
48 | }
49 |
50 | }
51 |
52 | private void fillInHeader(ProtocolMessage protocolMessage) {
53 | Header header = protocolMessage.getHeader();
54 | header.setMsgNum(msgNum++);
55 | header.setMsgType(protocolMessage.getBody().msgType());
56 | header.setMsgTime(CommonUtil.nowTime());
57 |
58 | // 下面的值,随机填。主要目的是证明协议支持多种类型格式
59 | header.setFlag((short)2);
60 | header.setOneByte((byte)3);
61 |
62 | Map attachment = new HashMap<>();
63 | attachment.put("name", "thinking_fioa");
64 | attachment.put("age", 18);
65 |
66 | header.getAttachment().putAll(attachment);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/KryoHolder.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 |
5 | /**
6 | * @author thinking_fioa
7 | * @createTime 2018/5/17
8 | * @description Kryo编码器是一个非线程安全,所以使用ThreadLocal
9 | */
10 |
11 |
12 | public class KryoHolder {
13 | private static ThreadLocal threadLocalKryo = new ThreadLocal(){
14 | @Override
15 | protected Kryo initialValue() {
16 | Kryo kryo = new KryoReflectionFactory();
17 |
18 | return kryo;
19 | }
20 | };
21 |
22 | public static Kryo get() {
23 | return threadLocalKryo.get();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/serialize/HeaderKryoSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo.serialize;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 | import com.esotericsoftware.kryo.Serializer;
5 | import com.esotericsoftware.kryo.io.Input;
6 | import com.esotericsoftware.kryo.io.Output;
7 | import org.apache.logging.log4j.LogManager;
8 | import org.apache.logging.log4j.Logger;
9 | import org.lwl.netty.constant.MessageTypeEnum;
10 | import org.lwl.netty.message.Header;
11 |
12 | import java.util.Map;
13 |
14 | /**
15 | * @author thinking_fioa
16 | * @createTime 2018/5/17
17 | * @description Kryo编码器。类: {@link Header}
18 | */
19 |
20 |
21 | public class HeaderKryoSerializer extends Serializer {
22 | private static final Logger LOGGER = LogManager.getLogger(HeaderKryoSerializer.class);
23 |
24 | @Override
25 | public void write(Kryo kryo, Output output, Header header) {
26 | KryoEncoder.getInstance().writeLong(output, header.getMsgNum());
27 | KryoEncoder.getInstance().writeByte(output, header.getMsgType().getMsgType());
28 | KryoEncoder.getInstance().writeString(output, header.getMsgTime());
29 | KryoEncoder.getInstance().writeShort(output, header.getFlag());
30 | KryoEncoder.getInstance().writeByte(output, header.getOneByte());
31 | KryoEncoder.getInstance().writeMap(kryo, output, header.getAttachment());
32 | }
33 |
34 | @Override
35 | public Header read(Kryo kryo, Input input, Class aClass) {
36 | long msgNum = KryoDecoder.getInstance().readLong(input);
37 | Byte msgType = KryoDecoder.getInstance().readByte(input);
38 | String msgTime = KryoDecoder.getInstance().readString(input);
39 | short flag = KryoDecoder.getInstance().readShort(input);
40 | byte oneByte = KryoDecoder.getInstance().readByte(input);
41 | Map attachment = KryoDecoder.getInstance().readMap(kryo, input);
42 |
43 | Header header = new Header();
44 | header.setMsgNum(msgNum);
45 | header.setMsgType(MessageTypeEnum.getMsgTypeEnum(msgType));
46 | header.setMsgTime(msgTime);
47 | header.setFlag(flag);
48 | header.setOneByte(oneByte);
49 | header.setAttachment(attachment);
50 |
51 | return header;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/serialize/KryoDecoder.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo.serialize;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 | import com.esotericsoftware.kryo.io.Input;
5 |
6 | import java.util.ArrayList;
7 | import java.util.HashMap;
8 | import java.util.List;
9 | import java.util.Map;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/5/12
14 | * @description
15 | */
16 |
17 |
18 | public class KryoDecoder {
19 |
20 | private static final KryoDecoder INSTANCE = new KryoDecoder();
21 |
22 | public static KryoDecoder getInstance() {
23 | return INSTANCE;
24 | }
25 |
26 | @SuppressWarnings("unchecked")
27 | public List readList(Kryo kryo, Input input, Class clazz) {
28 | int size = input.readInt();
29 | if(-1 == size) {
30 | return null;
31 | }
32 | if( 0 == size) {
33 | return new ArrayList<>();
34 | }
35 |
36 | List list = new ArrayList<>(size);
37 | for(int i =0;i readMap(Kryo kryo, Input input) {
45 | int size = input.readInt();
46 | if(-1 == size) {
47 | return null;
48 | }
49 | if(0 == size) {
50 | return new HashMap();
51 | }
52 |
53 | Map valueMap = new HashMap(size);
54 | for(int i = 0; i {
22 | private static final Logger LOGGER = LogManager.getLogger(ProtocolMessageKryoSerializer.class);
23 |
24 | @Override
25 | public void write(Kryo kryo, Output output, ProtocolMessage protocolMessage) {
26 | KryoEncoder.getInstance().writeObject(kryo, output, protocolMessage.getHeader());
27 | KryoEncoder.getInstance().writeObject(kryo, output, protocolMessage.getBody());
28 | KryoEncoder.getInstance().writeObject(kryo, output, protocolMessage.getTail());
29 | }
30 |
31 | @Override
32 | public ProtocolMessage read(Kryo kryo, Input input, Class aClass) {
33 | Header header = (Header)KryoDecoder.getInstance().readObject(kryo, input);
34 | Body body = (Body)KryoDecoder.getInstance().readObject(kryo, input);
35 | Tail tail = (Tail)KryoDecoder.getInstance().readObject(kryo, input);
36 |
37 | return ProtocolMessage.createMsgOfDecode(header, body, tail);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/serialize/TailKryoSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo.serialize;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 | import com.esotericsoftware.kryo.Serializer;
5 | import com.esotericsoftware.kryo.io.Input;
6 | import com.esotericsoftware.kryo.io.Output;
7 | import org.lwl.netty.message.Tail;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/5/17
12 | * @description
13 | */
14 |
15 |
16 | public class TailKryoSerializer extends Serializer {
17 |
18 | @Override
19 | public void write(Kryo kryo, Output output, Tail tail) {
20 | KryoEncoder.getInstance().writeInt(output, tail.getCheckSum());
21 | }
22 |
23 | @Override
24 | public Tail read(Kryo kryo, Input input, Class aClass) {
25 | int checkSum = KryoDecoder.getInstance().readInt(input);
26 |
27 | Tail tail = new Tail();
28 | tail.setCheckSum(checkSum);
29 |
30 | return tail;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/serialize/body/DefaultBodyKryoSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo.serialize.body;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 | import com.esotericsoftware.kryo.Serializer;
5 | import com.esotericsoftware.kryo.io.Input;
6 | import com.esotericsoftware.kryo.io.Output;
7 | import org.lwl.netty.message.Body;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/5/26
12 | * @description
13 | */
14 |
15 |
16 | public final class DefaultBodyKryoSerializer extends Serializer {
17 | @Override
18 | public void write(Kryo kryo, Output output, Body body) {
19 |
20 | }
21 |
22 | @Override
23 | public Body read(Kryo kryo, Input input, Class aClass) {
24 | return new Body();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/serialize/body/HtReqBodyKryoSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo.serialize.body;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 | import com.esotericsoftware.kryo.Serializer;
5 | import com.esotericsoftware.kryo.io.Input;
6 | import com.esotericsoftware.kryo.io.Output;
7 | import org.lwl.netty.message.body.HeartbeatReqBody;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/6/10
12 | * @description
13 | */
14 |
15 |
16 | public class HtReqBodyKryoSerializer extends Serializer {
17 | @Override
18 | public void write(Kryo kryo, Output output, HeartbeatReqBody heartbeatReqBody) {
19 |
20 | }
21 |
22 | @Override
23 | public HeartbeatReqBody read(Kryo kryo, Input input, Class aClass) {
24 | return new HeartbeatReqBody();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/serialize/body/HtRespBodyKryoSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo.serialize.body;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 | import com.esotericsoftware.kryo.Serializer;
5 | import com.esotericsoftware.kryo.io.Input;
6 | import com.esotericsoftware.kryo.io.Output;
7 | import org.lwl.netty.message.body.HeartbeatRespBody;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/6/10
12 | * @description
13 | */
14 |
15 |
16 | public class HtRespBodyKryoSerializer extends Serializer {
17 | @Override
18 | public void write(Kryo kryo, Output output, HeartbeatRespBody heartbeatRespBody) {
19 |
20 | }
21 |
22 | @Override
23 | public HeartbeatRespBody read(Kryo kryo, Input input, Class aClass) {
24 | return new HeartbeatRespBody();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/serialize/body/LoginReqBodyKryoSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo.serialize.body;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 | import com.esotericsoftware.kryo.Serializer;
5 | import com.esotericsoftware.kryo.io.Input;
6 | import com.esotericsoftware.kryo.io.Output;
7 | import org.lwl.netty.codec.other.kryo.serialize.KryoDecoder;
8 | import org.lwl.netty.codec.other.kryo.serialize.KryoEncoder;
9 | import org.lwl.netty.message.body.LoginReqBody;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/6/10
14 | * @description
15 | */
16 |
17 |
18 | public class LoginReqBodyKryoSerializer extends Serializer {
19 | @Override
20 | public void write(Kryo kryo, Output output, LoginReqBody login) {
21 | KryoEncoder.getInstance().writeString(output, login.getUserName());
22 | KryoEncoder.getInstance().writeString(output, login.getPassword());
23 | }
24 |
25 | @Override
26 | public LoginReqBody read(Kryo kryo, Input input, Class aClass) {
27 | String userName = KryoDecoder.getInstance().readString(input);
28 | String password = KryoDecoder.getInstance().readString(input);
29 |
30 | LoginReqBody loginReqBody = new LoginReqBody();
31 | loginReqBody.setUserName(userName);
32 | loginReqBody.setPassword(password);
33 |
34 | return loginReqBody;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/serialize/body/LoginRespBodyKryoSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo.serialize.body;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 | import com.esotericsoftware.kryo.Serializer;
5 | import com.esotericsoftware.kryo.io.Input;
6 | import com.esotericsoftware.kryo.io.Output;
7 | import org.lwl.netty.message.body.LoginRespBody;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/6/10
12 | * @description
13 | */
14 |
15 |
16 | public class LoginRespBodyKryoSerializer extends Serializer {
17 | @Override
18 | public void write(Kryo kryo, Output output, LoginRespBody loginRespBody) {
19 |
20 | }
21 |
22 | @Override
23 | public LoginRespBody read(Kryo kryo, Input input, Class aClass) {
24 | return new LoginRespBody();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/serialize/body/LogoutBodyKryoSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo.serialize.body;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 | import com.esotericsoftware.kryo.Serializer;
5 | import com.esotericsoftware.kryo.io.Input;
6 | import com.esotericsoftware.kryo.io.Output;
7 | import org.lwl.netty.message.body.LogoutBody;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/6/10
12 | * @description
13 | */
14 |
15 |
16 | public class LogoutBodyKryoSerializer extends Serializer {
17 | @Override
18 | public void write(Kryo kryo, Output output, LogoutBody logoutBody) {
19 |
20 | }
21 |
22 | @Override
23 | public LogoutBody read(Kryo kryo, Input input, Class aClass) {
24 | return new LogoutBody();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/serialize/body/ProtocolDataBodyKryoSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo.serialize.body;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 | import com.esotericsoftware.kryo.Serializer;
5 | import com.esotericsoftware.kryo.io.Input;
6 | import com.esotericsoftware.kryo.io.Output;
7 | import org.lwl.netty.codec.other.kryo.serialize.KryoDecoder;
8 | import org.lwl.netty.codec.other.kryo.serialize.KryoEncoder;
9 | import org.lwl.netty.message.body.ProtocolDataBody;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/6/10
14 | * @description
15 | */
16 |
17 |
18 | public class ProtocolDataBodyKryoSerializer extends Serializer {
19 | @Override
20 | public void write(Kryo kryo, Output output, ProtocolDataBody dataBody) {
21 | KryoEncoder.getInstance().writeLong(output, dataBody.getPkgSum());
22 | KryoEncoder.getInstance().writeLong(output, dataBody.getPkgSequenceNum());
23 | KryoEncoder.getInstance().writeInt(output, dataBody.getContentLen());
24 | KryoEncoder.getInstance().writeBytes(output, dataBody.getContent());
25 | }
26 |
27 | @Override
28 | public ProtocolDataBody read(Kryo kryo, Input input, Class aClass) {
29 | long pkgSum = KryoDecoder.getInstance().readLong(input);
30 | long pkgSequenceNum = KryoDecoder.getInstance().readLong(input);
31 | int contentLen = KryoDecoder.getInstance().readInt(input);
32 | byte [] content = new byte[contentLen];
33 | KryoDecoder.getInstance().readBytes(input, content);
34 |
35 | ProtocolDataBody dataBody = new ProtocolDataBody();
36 | dataBody.setPkgSum(pkgSum);
37 | dataBody.setPkgSequenceNum(pkgSequenceNum);
38 | dataBody.setContentLen(contentLen);
39 | dataBody.setContent(content);
40 |
41 | return new ProtocolDataBody();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/kryo/serialize/body/ProtocolSubBodyKryoSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.kryo.serialize.body;
2 |
3 | import com.esotericsoftware.kryo.Kryo;
4 | import com.esotericsoftware.kryo.Serializer;
5 | import com.esotericsoftware.kryo.io.Input;
6 | import com.esotericsoftware.kryo.io.Output;
7 | import org.lwl.netty.codec.other.kryo.serialize.KryoDecoder;
8 | import org.lwl.netty.codec.other.kryo.serialize.KryoEncoder;
9 | import org.lwl.netty.constant.ProtocolDataType;
10 | import org.lwl.netty.message.body.ProtocolSubBody;
11 |
12 | import java.util.List;
13 |
14 | /**
15 | * @author thinking_fioa
16 | * @createTime 2018/6/10
17 | * @description
18 | */
19 |
20 |
21 | public class ProtocolSubBodyKryoSerializer extends Serializer {
22 | @Override
23 | public void write(Kryo kryo, Output output, ProtocolSubBody subBody) {
24 | KryoEncoder.getInstance().writeList(kryo, output, subBody.getDataTypeList());
25 | }
26 |
27 | @Override
28 | public ProtocolSubBody read(Kryo kryo, Input input, Class aClass) {
29 | List dataTypeList = KryoDecoder.getInstance().readList(kryo, input, ProtocolDataType.class);
30 |
31 | ProtocolSubBody subBody = new ProtocolSubBody();
32 | subBody.setDataTypeList(dataTypeList);
33 |
34 | return new ProtocolSubBody();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/MarshallingDecoderAdapter.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.handler.codec.marshalling.MarshallingDecoder;
6 | import io.netty.handler.codec.marshalling.UnmarshallerProvider;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/5/13
11 | * @description
12 | */
13 |
14 |
15 | public class MarshallingDecoderAdapter extends MarshallingDecoder{
16 |
17 | public MarshallingDecoderAdapter(UnmarshallerProvider provider) {
18 | super(provider);
19 | }
20 |
21 | public MarshallingDecoderAdapter(UnmarshallerProvider provider, int maxObjectSize) {
22 | super(provider, maxObjectSize);
23 | }
24 |
25 | @Override
26 | public Object decode(ChannelHandlerContext ctx, ByteBuf inByteBuf) throws Exception {
27 | return super.decode(ctx, inByteBuf);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/MarshallingEncoderAdapter.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.handler.codec.marshalling.MarshallerProvider;
6 | import io.netty.handler.codec.marshalling.MarshallingEncoder;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/5/13
11 | * @description
12 | */
13 |
14 |
15 | public class MarshallingEncoderAdapter extends MarshallingEncoder {
16 |
17 | public MarshallingEncoderAdapter(MarshallerProvider provider) {
18 | super(provider);
19 | }
20 |
21 | @Override
22 | public void encode(ChannelHandlerContext ctx, Object msg, ByteBuf outByteBuf) throws Exception {
23 | super.encode(ctx, msg, outByteBuf);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/serialize/HeaderMslSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling.serialize;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import org.lwl.netty.codec.other.marshalling.MslDecoder;
6 | import org.lwl.netty.codec.other.marshalling.MslEncoder;
7 | import org.lwl.netty.constant.MessageTypeEnum;
8 | import org.lwl.netty.message.Header;
9 |
10 | import java.util.Map;
11 |
12 | /**
13 | * @author thinking_fioa
14 | * @createTime 2018/5/15
15 | * @description
16 | */
17 |
18 | public class HeaderMslSerializer {
19 |
20 | private static final HeaderMslSerializer INSTANCE = new HeaderMslSerializer();
21 | private HeaderMslSerializer(){}
22 |
23 | public static HeaderMslSerializer getInstance() {
24 | return INSTANCE;
25 | }
26 |
27 | public void serialize(ChannelHandlerContext ctx, ByteBuf outByteBuf, Header header) throws Exception {
28 | MslEncoder.getInstance().writeLong(outByteBuf, header.getMsgNum());
29 | MslEncoder.getInstance().writeByte(outByteBuf, header.getMsgType().getMsgType());
30 | MslEncoder.getInstance().writeString(outByteBuf, header.getMsgTime());
31 | MslEncoder.getInstance().writeShort(outByteBuf, header.getFlag());
32 | MslEncoder.getInstance().writeByte(outByteBuf, header.getOneByte());
33 | MslEncoder.getInstance().writeMap(ctx, outByteBuf, header.getAttachment());
34 | }
35 |
36 | public Header deserialize(ChannelHandlerContext ctx, ByteBuf inByteBuf) throws Exception{
37 | long msgNum = MslDecoder.getInstance().readLong(inByteBuf);
38 | Byte msgType = MslDecoder.getInstance().readByte(inByteBuf);
39 | String msgTime = MslDecoder.getInstance().readString(inByteBuf);
40 | short flag = MslDecoder.getInstance().readShort(inByteBuf);
41 | byte oneByte = MslDecoder.getInstance().readByte(inByteBuf);
42 | Map attachment = MslDecoder.getInstance().readMap(ctx, inByteBuf);
43 |
44 | Header header = new Header();
45 | header.setMsgNum(msgNum);
46 | header.setMsgType(MessageTypeEnum.getMsgTypeEnum(msgType));
47 | header.setMsgTime(msgTime);
48 | header.setFlag(flag);
49 | header.setOneByte(oneByte);
50 | header.setAttachment(attachment);
51 |
52 | return header;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/serialize/IBodyMslSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling.serialize;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import org.lwl.netty.message.Body;
6 |
7 | /**
8 | * @author thinking_fioa
9 | * @createTime 2018/5/15
10 | * @description
11 | */
12 |
13 |
14 | public interface IBodyMslSerializer {
15 |
16 | public void serialize(ChannelHandlerContext ctx, ByteBuf outByteBuf, Body body) throws Exception;
17 |
18 | public T deserialize(ChannelHandlerContext ctx, ByteBuf inByteBuf) throws Exception;
19 | }
20 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/serialize/TailMslSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling.serialize;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import org.lwl.netty.codec.other.marshalling.MslDecoder;
6 | import org.lwl.netty.codec.other.marshalling.MslEncoder;
7 | import org.lwl.netty.message.Tail;
8 | import org.lwl.netty.util.CommonUtil;
9 |
10 | /**
11 | * @author thinking_fioa
12 | * @createTime 2018/5/15
13 | * @description
14 | */
15 |
16 |
17 | public class TailMslSerializer {
18 |
19 | private static final TailMslSerializer INSTANCE = new TailMslSerializer();
20 | private TailMslSerializer(){}
21 |
22 | public static TailMslSerializer getInstance() {
23 | return INSTANCE;
24 | }
25 |
26 | public void serialize(ChannelHandlerContext ctx, ByteBuf outByteBuf, Tail msg) throws Exception {
27 | int checkSum = CommonUtil.calCheckSum(outByteBuf, outByteBuf.writerIndex());
28 | MslEncoder.getInstance().writeInt(outByteBuf, checkSum);
29 | }
30 |
31 | public Tail deserialize(ChannelHandlerContext ctx, ByteBuf inByteBuf) throws Exception {
32 | int checkSum = MslDecoder.getInstance().readInt(inByteBuf);
33 |
34 | Tail tail = new Tail();
35 | tail.setCheckSum(checkSum);
36 |
37 | return tail;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/serialize/body/DefaultBodyMslSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import org.lwl.netty.codec.other.marshalling.serialize.IBodyMslSerializer;
6 | import org.lwl.netty.message.Body;
7 |
8 | /**
9 | * @author thinking_fioa
10 | * @createTime 2018/5/26
11 | * @description
12 | */
13 |
14 |
15 | public final class DefaultBodyMslSerializer implements IBodyMslSerializer {
16 |
17 | private static final DefaultBodyMslSerializer INSTANCE = new DefaultBodyMslSerializer();
18 | private DefaultBodyMslSerializer(){}
19 |
20 | public static DefaultBodyMslSerializer getInstance() {
21 | return INSTANCE;
22 | }
23 |
24 | @Override
25 | public void serialize(ChannelHandlerContext ctx, ByteBuf outByteBuf, Body body) {
26 |
27 | }
28 |
29 | @Override
30 | public Body deserialize(ChannelHandlerContext ctx, ByteBuf inByteBuf) {
31 | return new Body();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/serialize/body/HeartbeatReqBodyMslSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import org.lwl.netty.codec.other.marshalling.serialize.IBodyMslSerializer;
6 | import org.lwl.netty.message.Body;
7 | import org.lwl.netty.message.body.HeartbeatReqBody;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/5/26
12 | * @description
13 | */
14 |
15 |
16 | public final class HeartbeatReqBodyMslSerializer implements IBodyMslSerializer {
17 |
18 | private static final HeartbeatReqBodyMslSerializer INSTANCE = new HeartbeatReqBodyMslSerializer();
19 | private HeartbeatReqBodyMslSerializer(){}
20 |
21 | public static HeartbeatReqBodyMslSerializer getInstance() {
22 | return INSTANCE;
23 | }
24 |
25 |
26 | @Override
27 | public void serialize(ChannelHandlerContext ctx, ByteBuf outByteBuf, Body body) {
28 |
29 | }
30 |
31 | @Override
32 | public HeartbeatReqBody deserialize(ChannelHandlerContext ctx, ByteBuf inByteBuf) {
33 | return new HeartbeatReqBody();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/serialize/body/HeartbeatRespBodyMslSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import org.lwl.netty.codec.other.marshalling.serialize.IBodyMslSerializer;
6 | import org.lwl.netty.message.Body;
7 | import org.lwl.netty.message.body.HeartbeatRespBody;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/5/26
12 | * @description
13 | */
14 |
15 |
16 | public final class HeartbeatRespBodyMslSerializer implements IBodyMslSerializer {
17 |
18 | private static final HeartbeatRespBodyMslSerializer INSTANCE = new HeartbeatRespBodyMslSerializer();
19 | private HeartbeatRespBodyMslSerializer(){}
20 |
21 | public static HeartbeatRespBodyMslSerializer getInstance() {
22 | return INSTANCE;
23 | }
24 |
25 |
26 | @Override
27 | public void serialize(ChannelHandlerContext ctx, ByteBuf outByteBuf, Body body) {
28 |
29 | }
30 |
31 | @Override
32 | public HeartbeatRespBody deserialize(ChannelHandlerContext ctx, ByteBuf inByteBuf) {
33 | return new HeartbeatRespBody();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/serialize/body/LoginReqBodyMslSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import org.lwl.netty.codec.other.marshalling.MslDecoder;
6 | import org.lwl.netty.codec.other.marshalling.MslEncoder;
7 | import org.lwl.netty.codec.other.marshalling.serialize.IBodyMslSerializer;
8 | import org.lwl.netty.message.Body;
9 | import org.lwl.netty.message.body.LoginReqBody;
10 |
11 | import java.io.UnsupportedEncodingException;
12 |
13 | /**
14 | * @author thinking_fioa
15 | * @createTime 2018/5/26
16 | * @description
17 | */
18 |
19 |
20 | public final class LoginReqBodyMslSerializer implements IBodyMslSerializer {
21 |
22 | private static final LoginReqBodyMslSerializer INSTANCE = new LoginReqBodyMslSerializer();
23 | private LoginReqBodyMslSerializer(){}
24 |
25 | public static LoginReqBodyMslSerializer getInstance() {
26 | return INSTANCE;
27 | }
28 |
29 |
30 | @Override
31 | public void serialize(ChannelHandlerContext ctx, ByteBuf outByteBuf, Body body) throws UnsupportedEncodingException {
32 | LoginReqBody login = (LoginReqBody)body;
33 | MslEncoder.getInstance().writeString(outByteBuf, login.getUserName());
34 | MslEncoder.getInstance().writeString(outByteBuf, login.getPassword());
35 | }
36 |
37 | @Override
38 | public LoginReqBody deserialize(ChannelHandlerContext ctx, ByteBuf inByteBuf) throws UnsupportedEncodingException {
39 | String userName = MslDecoder.getInstance().readString(inByteBuf);
40 | String password = MslDecoder.getInstance().readString(inByteBuf);
41 |
42 | LoginReqBody loginReqBody = new LoginReqBody();
43 | loginReqBody.setUserName(userName);
44 | loginReqBody.setPassword(password);
45 |
46 | return loginReqBody;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/serialize/body/LoginRespBodyMslSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import org.lwl.netty.codec.other.marshalling.serialize.IBodyMslSerializer;
6 | import org.lwl.netty.message.Body;
7 | import org.lwl.netty.message.body.LoginRespBody;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/5/26
12 | * @description
13 | */
14 |
15 |
16 | public final class LoginRespBodyMslSerializer implements IBodyMslSerializer {
17 |
18 | private static final LoginRespBodyMslSerializer INSTANCE = new LoginRespBodyMslSerializer();
19 | private LoginRespBodyMslSerializer(){}
20 |
21 | public static LoginRespBodyMslSerializer getInstance() {
22 | return INSTANCE;
23 | }
24 |
25 |
26 | @Override
27 | public void serialize(ChannelHandlerContext ctx, ByteBuf outByteBuf, Body body) {
28 |
29 | }
30 |
31 | @Override
32 | public LoginRespBody deserialize(ChannelHandlerContext ctx, ByteBuf inByteBuf) {
33 | return new LoginRespBody();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/serialize/body/LogoutBodyMslSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import org.lwl.netty.codec.other.marshalling.serialize.IBodyMslSerializer;
6 | import org.lwl.netty.message.Body;
7 | import org.lwl.netty.message.body.LogoutBody;
8 |
9 | /**
10 | * @author thinking_fioa
11 | * @createTime 2018/5/26
12 | * @description
13 | */
14 |
15 |
16 | public final class LogoutBodyMslSerializer implements IBodyMslSerializer {
17 |
18 | private static final LogoutBodyMslSerializer INSTANCE = new LogoutBodyMslSerializer();
19 | private LogoutBodyMslSerializer(){}
20 |
21 | public static LogoutBodyMslSerializer getInstance() {
22 | return INSTANCE;
23 | }
24 |
25 |
26 | @Override
27 | public void serialize(ChannelHandlerContext ctx, ByteBuf outByteBuf, Body body) {
28 |
29 | }
30 |
31 | @Override
32 | public LogoutBody deserialize(ChannelHandlerContext ctx, ByteBuf inByteBuf) {
33 | return new LogoutBody();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/serialize/body/ProtocolDataBodyMslSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import org.lwl.netty.codec.other.marshalling.MslDecoder;
6 | import org.lwl.netty.codec.other.marshalling.MslEncoder;
7 | import org.lwl.netty.codec.other.marshalling.serialize.IBodyMslSerializer;
8 | import org.lwl.netty.message.Body;
9 | import org.lwl.netty.message.body.ProtocolDataBody;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/5/26
14 | * @description
15 | */
16 |
17 |
18 | public final class ProtocolDataBodyMslSerializer implements IBodyMslSerializer {
19 |
20 | private static final ProtocolDataBodyMslSerializer INSTANCE = new ProtocolDataBodyMslSerializer();
21 | private ProtocolDataBodyMslSerializer(){}
22 |
23 | public static ProtocolDataBodyMslSerializer getInstance() {
24 | return INSTANCE;
25 | }
26 |
27 | @Override
28 | public void serialize(ChannelHandlerContext ctx, ByteBuf outByteBuf, Body body) {
29 | ProtocolDataBody dataBody = (ProtocolDataBody)body;
30 |
31 | MslEncoder.getInstance().writeLong(outByteBuf, dataBody.getPkgSum());
32 | MslEncoder.getInstance().writeLong(outByteBuf, dataBody.getPkgSequenceNum());
33 | MslEncoder.getInstance().writeInt(outByteBuf, dataBody.getContentLen());
34 | MslEncoder.getInstance().writeBytes(outByteBuf, dataBody.getContent());
35 | }
36 |
37 | @Override
38 | public ProtocolDataBody deserialize(ChannelHandlerContext ctx, ByteBuf inByteBuf) {
39 | long pkgSum = MslDecoder.getInstance().readLong(inByteBuf);
40 | long pkgSequenceNum = MslDecoder.getInstance().readLong(inByteBuf);
41 | int contentLen = MslDecoder.getInstance().readInt(inByteBuf);
42 | byte [] content = new byte[contentLen];
43 | MslDecoder.getInstance().readBytes(inByteBuf, content);
44 |
45 | ProtocolDataBody dataBody = new ProtocolDataBody();
46 | dataBody.setPkgSum(pkgSum);
47 | dataBody.setPkgSequenceNum(pkgSequenceNum);
48 | dataBody.setContentLen(contentLen);
49 | dataBody.setContent(content);
50 |
51 | return new ProtocolDataBody();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/other/marshalling/serialize/body/ProtocolSubBodyMslSerializer.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.other.marshalling.serialize.body;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import org.lwl.netty.codec.other.marshalling.MslDecoder;
6 | import org.lwl.netty.codec.other.marshalling.MslEncoder;
7 | import org.lwl.netty.codec.other.marshalling.serialize.IBodyMslSerializer;
8 | import org.lwl.netty.constant.ProtocolDataType;
9 | import org.lwl.netty.message.Body;
10 | import org.lwl.netty.message.body.ProtocolSubBody;
11 |
12 | import java.util.List;
13 |
14 | /**
15 | * @author thinking_fioa
16 | * @createTime 2018/5/26
17 | * @description
18 | */
19 |
20 |
21 | public final class ProtocolSubBodyMslSerializer implements IBodyMslSerializer {
22 |
23 | private static final ProtocolSubBodyMslSerializer INSTANCE = new ProtocolSubBodyMslSerializer();
24 | private ProtocolSubBodyMslSerializer(){}
25 |
26 | public static ProtocolSubBodyMslSerializer getInstance() {
27 | return INSTANCE;
28 | }
29 |
30 |
31 | @Override
32 | public void serialize(ChannelHandlerContext ctx, ByteBuf outByteBuf, Body body) throws Exception {
33 | ProtocolSubBody subBody = (ProtocolSubBody)body;
34 | MslEncoder.getInstance().writeList(ctx, outByteBuf, subBody.getDataTypeList());
35 | }
36 |
37 | @Override
38 | public ProtocolSubBody deserialize(ChannelHandlerContext ctx, ByteBuf inByteBuf) throws Exception {
39 |
40 | List dataTypeList = MslDecoder.getInstance().readList(ctx, inByteBuf, ProtocolDataType.class);
41 | ProtocolSubBody subBody = new ProtocolSubBody();
42 | subBody.setDataTypeList(dataTypeList);
43 |
44 | return new ProtocolSubBody();
45 |
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/codec/protobuf/ProtobufPostDecoder.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.codec.protobuf;
2 |
3 | /**
4 | * @author thinking_fioa
5 | * @createTime 2018/7/15
6 | * @description Protobuf解码器后做的校验。比如:checkSum校验
7 | */
8 |
9 |
10 | public class ProtobufPostDecoder {
11 | }
12 |
--------------------------------------------------------------------------------
/netty-private-protocol/src/main/java/org/lwl/netty/config/BaseConfig.java:
--------------------------------------------------------------------------------
1 | package org.lwl.netty.config;
2 |
3 | import org.apache.logging.log4j.LogManager;
4 | import org.apache.logging.log4j.Logger;
5 |
6 | import java.io.IOException;
7 | import java.util.HashMap;
8 | import java.util.Map;
9 | import java.util.Properties;
10 |
11 | /**
12 | * @author thinking_fioa
13 | * @createTime 2018/5/15
14 | * @description
15 | */
16 |
17 |
18 | public class BaseConfig {
19 | private static final Logger LOGGER = LogManager.getLogger(BaseConfig.class);
20 |
21 | public static String getStringProperty(Map props, String key, String defaultVal) {
22 | Object value = props.get(key);
23 | if(null == value) {
24 | return defaultVal;
25 | }
26 |
27 | return String.valueOf(props.get(key)).trim();
28 | }
29 |
30 | public static int getIntProperty(Map props, String key, int defaultVal) {
31 | Object value = props.get(key);
32 | if(null == value) {
33 | return defaultVal;
34 | }
35 |
36 | return Integer.parseInt(props.get(key).trim());
37 | }
38 |
39 | public static long getLongProperty(Map props, String key, long defaultVal) {
40 | Object value = props.get(key);
41 | if(null == value) {
42 | return defaultVal;
43 | }
44 |
45 | return Long.parseLong(props.get(key).trim());
46 | }
47 |
48 | public static byte getByteProperty(Map props, String key, byte defaultVal) {
49 | Object value = props.get(key);
50 | if(null == value) {
51 | return defaultVal;
52 | }
53 |
54 | return Byte.parseByte(props.get(key).trim());
55 | }
56 |
57 | public static boolean getBooleanProperty(Map props, String key, Boolean defaultVal) {
58 | Object value = props.get(key);
59 | if(null == value) {
60 | return defaultVal;
61 | }
62 |
63 | return Boolean.parseBoolean(props.get(key).trim());
64 | }
65 |
66 | public static Map getConfigSettings(Properties pros) throws IOException {
67 | Map map = new HashMap();
68 | for (Map.Entry