Repository: BazingaLyn/netty-study
Branch: master
Commit: 0b6ad325ed9c
Files: 149
Total size: 357.3 KB
Directory structure:
gitextract_h9fdvoav/
├── README.md
├── pom.xml
└── src/
└── main/
├── java/
│ └── com/
│ └── lyncc/
│ └── netty/
│ ├── attributeMap/
│ │ ├── AttributeMapConstant.java
│ │ ├── HelloWorld2ClientHandler.java
│ │ ├── HelloWorldClient.java
│ │ ├── HelloWorldClientHandler.java
│ │ ├── HelloWorldServer.java
│ │ ├── HelloWorldServerHandler.java
│ │ └── NettyChannel.java
│ ├── codec/
│ │ ├── custom/
│ │ │ ├── ProtocolDecoder.java
│ │ │ ├── ProtocolEncoder.java
│ │ │ ├── ProtocolHeader.java
│ │ │ └── ProtocolMsg.java
│ │ ├── jackson/
│ │ │ ├── JacksonClient.java
│ │ │ ├── JacksonClientHandler.java
│ │ │ ├── JacksonClientHandlerInitializer.java
│ │ │ ├── JacksonServer.java
│ │ │ ├── JacksonServerHandler.java
│ │ │ ├── JacksonServerHandlerInitializer.java
│ │ │ ├── User.java
│ │ │ ├── UserDecoder.java
│ │ │ ├── UserEncoder.java
│ │ │ └── UserMapper.java
│ │ ├── lengthFieldBasedFrame/
│ │ │ ├── CustomClient.java
│ │ │ ├── CustomClientHandler.java
│ │ │ ├── CustomDecoder.java
│ │ │ ├── CustomEncoder.java
│ │ │ ├── CustomMsg.java
│ │ │ ├── CustomServer.java
│ │ │ └── CustomServerHandler.java
│ │ └── protobuf/
│ │ ├── SubReqClient.java
│ │ ├── SubReqClientHandler.java
│ │ ├── SubReqServer.java
│ │ ├── SubReqServerHandler.java
│ │ ├── SubscribeReq.proto
│ │ ├── SubscribeReqProto.java
│ │ ├── SubscribeResp.proto
│ │ ├── SubscribeRespProto.java
│ │ ├── TestSubscribeReqProto.java
│ │ └── demo/
│ │ ├── ProtoBufClient.java
│ │ ├── ProtoBufClientHandler.java
│ │ ├── ProtoBufServer.java
│ │ ├── ProtoBufServerHandler.java
│ │ ├── RichMan.proto
│ │ └── RichManProto.java
│ ├── component/
│ │ ├── channelhandler/
│ │ │ ├── BaseClient.java
│ │ │ ├── BaseClient1Handler.java
│ │ │ ├── BaseClient2Handler.java
│ │ │ ├── BaseServer.java
│ │ │ └── BaseServerHandler.java
│ │ └── simplehandler/
│ │ ├── BaseClient.java
│ │ ├── BaseClientHandler.java
│ │ ├── BaseServer.java
│ │ └── BaseServerHandler.java
│ ├── concept/
│ │ └── HelloWorldConcept.java
│ ├── heartbeat/
│ │ ├── BaseClient.java
│ │ ├── BaseClientHandler.java
│ │ ├── BaseServer.java
│ │ └── BaseServerHandler.java
│ ├── heartbeat2/
│ │ ├── AskMsg.java
│ │ ├── AskParams.java
│ │ ├── BaseMsg.java
│ │ ├── Constants.java
│ │ ├── LoginMsg.java
│ │ ├── MsgType.java
│ │ ├── NettyChannelMap.java
│ │ ├── NettyClientBootstrap.java
│ │ ├── NettyClientHandler.java
│ │ ├── NettyServerBootstrap.java
│ │ ├── NettyServerHandler.java
│ │ ├── PingMsg.java
│ │ ├── ReplyBody.java
│ │ ├── ReplyClientBody.java
│ │ ├── ReplyMsg.java
│ │ └── ReplyServerBody.java
│ ├── heartbeats/
│ │ ├── HeartBeatClientHandler.java
│ │ ├── HeartBeatServer.java
│ │ ├── HeartBeatServerHandler.java
│ │ └── HeartBeatsClient.java
│ ├── hello/
│ │ ├── HelloWorldClient.java
│ │ ├── HelloWorldClientHandler.java
│ │ ├── HelloWorldServer.java
│ │ └── HelloWorldServerHandler.java
│ ├── idle/
│ │ ├── AcceptorIdleStateTrigger.java
│ │ ├── ChannelHandlerHolder.java
│ │ ├── ConnectionWatchdog.java
│ │ ├── ConnectorIdleStateTrigger.java
│ │ ├── HeartBeatClientHandler.java
│ │ ├── HeartBeatServer.java
│ │ ├── HeartBeatServerHandler.java
│ │ └── HeartBeatsClient.java
│ ├── keepalive/
│ │ ├── Constants.java
│ │ ├── Heartbeat.java
│ │ ├── KeepAliveClient.java
│ │ ├── KeepAliveMessage.java
│ │ ├── KeepAliveServer.java
│ │ ├── KeepAliveServerInitializer.java
│ │ └── Utils.java
│ ├── nio/
│ │ ├── EchoClient.java
│ │ ├── MultiPortEchoServer.java
│ │ └── package-info.java
│ ├── production/
│ │ ├── ChannelHandlerHolder.java
│ │ ├── ConnectionWatchdog.java
│ │ ├── client/
│ │ │ └── connector/
│ │ │ ├── ClientConnector.java
│ │ │ ├── ConnectorIdleStateTrigger.java
│ │ │ ├── DefaultCommonClientConnector.java
│ │ │ ├── NettyClientConnector.java
│ │ │ └── package-info.java
│ │ ├── common/
│ │ │ ├── Acknowledge.java
│ │ │ ├── Heartbeats.java
│ │ │ ├── Message.java
│ │ │ ├── NativeSupport.java
│ │ │ ├── NettyCommonProtocol.java
│ │ │ ├── NettyEvent.java
│ │ │ ├── NettyEventType.java
│ │ │ ├── ServiceThread.java
│ │ │ ├── exception/
│ │ │ │ └── ConnectFailedException.java
│ │ │ └── package-info.java
│ │ ├── example/
│ │ │ ├── ClientConnectorStartup.java
│ │ │ ├── SrvAcceptorStartup.java
│ │ │ └── package-info.java
│ │ ├── serializer/
│ │ │ ├── Serializer.java
│ │ │ ├── SerializerHolder.java
│ │ │ └── protostuff/
│ │ │ └── ProtoStuffSerializer.java
│ │ └── srv/
│ │ └── acceptor/
│ │ ├── AcceptorIdleStateTrigger.java
│ │ ├── AcknowledgeEncoder.java
│ │ ├── ChannelEventListener.java
│ │ ├── DefaultCommonSrvAcceptor.java
│ │ ├── DefaultSrvAcceptor.java
│ │ ├── NettySrvAcceptor.java
│ │ ├── SrvAcceptor.java
│ │ └── package-info.java
│ └── stickpackage/
│ ├── correct/
│ │ ├── BaseClient.java
│ │ ├── BaseClientHandler.java
│ │ ├── BaseServer.java
│ │ └── BaseServerHandler.java
│ ├── delimiter/
│ │ ├── BaseClient.java
│ │ ├── BaseClientHandler.java
│ │ ├── BaseServer.java
│ │ └── BaseServerHandler.java
│ ├── error/
│ │ ├── BaseClient.java
│ │ ├── BaseClientHandler.java
│ │ ├── BaseServer.java
│ │ └── BaseServerHandler.java
│ └── myself/
│ ├── BaseClient.java
│ ├── BaseClientHandler.java
│ ├── BaseServer.java
│ └── BaseServerHandler.java
└── resources/
└── logback.xml
================================================
FILE CONTENTS
================================================
================================================
FILE: README.md
================================================
# netty-study
netty4.x知识点学习
### 1) [生产级别的心跳重连](https://github.com/BazingaLyn/netty-study/tree/master/src/main/java/com/lyncc/netty/idle)
### 2) [比较规范的netty的C/S端编写](https://github.com/BazingaLyn/netty-study/tree/master/src/main/java/com/lyncc/netty/production)
1)有心跳机制
2)有ACK检验机制
3)有重连机制
4)自定义交互协议
(代码是从Jupiter和RocketMQ中截出)
================================================
FILE: pom.xml
================================================
4.0.0
com.study
netty-study
0.0.1-SNAPSHOT
jar
netty-study
http://maven.apache.org
UTF-8
2.6.3
1.7.5
junit
junit
4.10
test
org.slf4j
slf4j-api
${slf4j.version}
io.netty
netty-all
4.0.21.Final
com.fasterxml.jackson.core
jackson-core
${version.jackson.core}
com.fasterxml.jackson.core
jackson-databind
${version.jackson.core}
com.google.protobuf
protobuf-java
2.6.1
io.protostuff
protostuff-core
1.3.5
io.protostuff
protostuff-runtime
1.3.5
org.objenesis
objenesis
2.1
ch.qos.logback
logback-classic
1.0.13
================================================
FILE: src/main/java/com/lyncc/netty/attributeMap/AttributeMapConstant.java
================================================
package com.lyncc.netty.attributeMap;
import io.netty.util.AttributeKey;
public class AttributeMapConstant {
public static final AttributeKey NETTY_CHANNEL_KEY = AttributeKey.valueOf("netty.channel");
}
================================================
FILE: src/main/java/com/lyncc/netty/attributeMap/HelloWorld2ClientHandler.java
================================================
package com.lyncc.netty.attributeMap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import java.util.HashSet;
public class HelloWorld2ClientHandler extends ChannelInboundHandlerAdapter {
public static final AttributeKey> NETTY_CHANNEL_KEY1 = AttributeKey.valueOf("netty.channel1");
@Override
public void channelActive(ChannelHandlerContext ctx) {
Attribute> attr = ctx.channel().attr(NETTY_CHANNEL_KEY1);
HashSet sets = attr.get();
if (sets == null) {
HashSet newSet = new HashSet();
sets = attr.setIfAbsent(newSet);
if(null == sets){
System.out.println("GGGGGGGGGGGGGGGGGGGGGG NULLLLLLLLLLL");
sets = newSet;
}
HashSet sets2 = attr.get();
System.out.println("RRRRRRRRRRRRRRRRR ==="+sets2.size());
for(Integer i :sets2){
System.out.println("value is GGGGGGGGGGG===="+i);
}
}
sets.add(1);
HashSet sets3 = attr.get();
System.out.println("RRRRRRRRRRRRRRRRR2 ==="+sets3.size());
System.out.println("HelloWorldC2ientHandler Active");
ctx.fireChannelActive();
}
public static void main(String[] args) {
Student student = new Student("1", 21);
Student s =student;
s.setAge(88);
System.out.println(student.getAge());
}
static class Student {
String id;
int age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String id, int age) {
super();
this.id = id;
this.age = age;
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
Attribute> attr = ctx.channel().attr(NETTY_CHANNEL_KEY1);
HashSet sets = attr.get();
if (sets == null) {
System.out.println("没有值啊");
}else{
for(Integer i :sets){
System.out.println("value is ===="+i);
}
}
System.out.println("HelloWorldClientHandler read Message:" + msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
================================================
FILE: src/main/java/com/lyncc/netty/attributeMap/HelloWorldClient.java
================================================
package com.lyncc.netty.attributeMap;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
public class HelloWorldClient {
static final String HOST = System.getProperty("host", "127.0.0.1");
static final int PORT = Integer.parseInt(System.getProperty("port", "8080"));
static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));
public static void main(String[] args) throws Exception {
initChannel();
}
public static void initChannel() throws InterruptedException{
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast("decoder", new StringDecoder());
p.addLast("encoder", new StringEncoder());
p.addLast(new HelloWorldClientHandler());
p.addLast(new HelloWorld2ClientHandler());
}
});
ChannelFuture future = b.connect(HOST, PORT).sync();
future.channel().writeAndFlush("hello Netty,Test attributeMap");
future.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
}
================================================
FILE: src/main/java/com/lyncc/netty/attributeMap/HelloWorldClientHandler.java
================================================
package com.lyncc.netty.attributeMap;
import static com.lyncc.netty.attributeMap.AttributeMapConstant.NETTY_CHANNEL_KEY;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.Attribute;
import java.util.Date;
public class HelloWorldClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) {
Attribute attr = ctx.channel().attr(NETTY_CHANNEL_KEY);
NettyChannel nChannel = attr.get();
if (nChannel == null) {
NettyChannel newNChannel = new NettyChannel("HelloWorld0Client", new Date());
nChannel = attr.setIfAbsent(newNChannel);
} else {
System.out.println("channelActive attributeMap 中是有值的");
System.out.println(nChannel.getName() + "=======" + nChannel.getCreateDate());
}
System.out.println("HelloWorldC0ientHandler Active");
ctx.fireChannelActive();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
Attribute attr = ctx.channel().attr(NETTY_CHANNEL_KEY);
NettyChannel nChannel = attr.get();
if (nChannel == null) {
NettyChannel newNChannel = new NettyChannel("HelloWorld0Client", new Date());
nChannel = attr.setIfAbsent(newNChannel);
} else {
System.out.println("channelRead attributeMap 中是有值的");
System.out.println(nChannel.getName() + "=======" + nChannel.getCreateDate());
}
System.out.println("HelloWorldClientHandler read Message:" + msg);
ctx.fireChannelRead(msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
================================================
FILE: src/main/java/com/lyncc/netty/attributeMap/HelloWorldServer.java
================================================
package com.lyncc.netty.attributeMap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import java.net.InetSocketAddress;
public class HelloWorldServer {
private int port;
public HelloWorldServer(int port) {
this.port = port;
}
public void start(){
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap sbs = new ServerBootstrap().group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer() {
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("decoder", new StringDecoder());
ch.pipeline().addLast("encoder", new StringEncoder());
ch.pipeline().addLast(new HelloWorldServerHandler());
};
}).option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
// 绑定端口,开始接收进来的连接
ChannelFuture future = sbs.bind(port).sync();
System.out.println("Server start listen at " + port );
future.channel().closeFuture().sync();
} catch (Exception e) {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int port;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
} else {
port = 8080;
}
new HelloWorldServer(port).start();
}
}
================================================
FILE: src/main/java/com/lyncc/netty/attributeMap/HelloWorldServerHandler.java
================================================
package com.lyncc.netty.attributeMap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class HelloWorldServerHandler extends ChannelInboundHandlerAdapter{
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("server channelRead..");
System.out.println(ctx.channel().remoteAddress()+"->Server :"+ msg.toString());
ctx.write("server write"+msg);
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
================================================
FILE: src/main/java/com/lyncc/netty/attributeMap/NettyChannel.java
================================================
package com.lyncc.netty.attributeMap;
import java.util.Date;
public class NettyChannel {
private String name;
private Date createDate;
public NettyChannel(String name,Date createDate) {
this.name = name;
this.createDate = createDate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
================================================
FILE: src/main/java/com/lyncc/netty/codec/custom/ProtocolDecoder.java
================================================
package com.lyncc.netty.codec.custom;
public class ProtocolDecoder{
}
================================================
FILE: src/main/java/com/lyncc/netty/codec/custom/ProtocolEncoder.java
================================================
package com.lyncc.netty.codec.custom;
import java.nio.charset.Charset;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
public class ProtocolEncoder extends MessageToByteEncoder {
@Override
protected void encode(ChannelHandlerContext ctx, ProtocolMsg msg, ByteBuf out) throws Exception {
if (null == msg || null == msg.getProtocolHeader()) {
throw new Exception("msg is null");
}
ProtocolHeader header = msg.getProtocolHeader();
String body = msg.getBody();
byte[] bodyBytes = body.getBytes(Charset.forName("utf-8"));
int bodySize = bodyBytes.length;
out.writeByte(header.getMagic());
out.writeByte(header.getMsgType());
out.writeShort(header.getReserve());
out.writeShort(header.getSn());
out.writeInt(bodySize);
out.writeBytes(bodyBytes);
}
}
================================================
FILE: src/main/java/com/lyncc/netty/codec/custom/ProtocolHeader.java
================================================
package com.lyncc.netty.codec.custom;
public class ProtocolHeader {
private byte magic;
private byte msgType;
private short reserve;
private short sn;
private int len;
public ProtocolHeader() {
}
public byte getMagic() {
return magic;
}
public void setMagic(byte magic) {
this.magic = magic;
}
public byte getMsgType() {
return msgType;
}
public void setMsgType(byte msgType) {
this.msgType = msgType;
}
public short getReserve() {
return reserve;
}
public void setReserve(short reserve) {
this.reserve = reserve;
}
public short getSn() {
return sn;
}
public void setSn(short sn) {
this.sn = sn;
}
public int getLen() {
return len;
}
public void setLen(int len) {
this.len = len;
}
public ProtocolHeader(byte magic, byte msgType, short reserve, short sn, int len) {
this.magic = magic;
this.msgType = msgType;
this.reserve = reserve;
this.sn = sn;
this.len = len;
}
}
================================================
FILE: src/main/java/com/lyncc/netty/codec/custom/ProtocolMsg.java
================================================
package com.lyncc.netty.codec.custom;
public class ProtocolMsg {
private ProtocolHeader protocolHeader = new ProtocolHeader();
private String body;
public ProtocolMsg() {
}
public ProtocolHeader getProtocolHeader() {
return protocolHeader;
}
public void setProtocolHeader(ProtocolHeader protocolHeader) {
this.protocolHeader = protocolHeader;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
================================================
FILE: src/main/java/com/lyncc/netty/codec/jackson/JacksonClient.java
================================================
package com.lyncc.netty.codec.jackson;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.util.ArrayList;
import java.util.List;
public class JacksonClient {
private final String host;
private final int port;
public JacksonClient(String host, int port){
this.host = host;
this.port = port;
}
public static void main(String[] args) throws Exception{
new JacksonClient("localhost", 8082).run();
}
public void run() throws Exception{
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(new JacksonClientHandlerInitializer());
Channel channel = bootstrap.connect(host, port).sync().channel();
// 发送对象
User user = new User();
user.setId(1);
user.setAge(21);
user.setName("BazingaLyncc");
List friends = new ArrayList();
friends.add("TED");
friends.add("MISS");
user.setFriends(friends);
channel.write(user);
channel.flush();
// 等待连接关闭
channel.closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
}
================================================
FILE: src/main/java/com/lyncc/netty/codec/jackson/JacksonClientHandler.java
================================================
package com.lyncc.netty.codec.jackson;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class JacksonClientHandler extends SimpleChannelInboundHandler