实验
- server
serverBootstrap.group(bossGroup, workGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
//.childOption(ChannelOption.SO_KEEPALIVE, true)
.childHandler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new ServerHandle());
}
});
ch.pipeline().addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));
服务端设置读超时
- ServerHandle
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println(msg.toString());
if (msg.equals("Heartbeat")) {
System.out.println("recv Heartbeat!");
ctx.write("has read message from server");
ctx.flush();
}
super.channelRead(ctx, msg);
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if(evt instanceof IdleStateEvent){
IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
if(idleStateEvent.state() == IdleState.READER_IDLE){
loss_connect_time++;
System.out.println(loss_connect_time);
if(loss_connect_time>2){
System.out.println("close");
ctx.channel().close();
}
}
}
super.userEventTriggered(ctx, evt);
}
- client
b.group(workGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("ping",new IdleStateHandler(0,4,0, TimeUnit.SECONDS));
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new ClientHandler());
}
});
client用ch.pipeline().addLast("ping",new IdleStateHandler(0,4,0, TimeUnit.SECONDS));
添加写超时
- ClientHandler
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
System.out.println("EventTriggered TIME : "+ new Date(System.currentTimeMillis()));
if(evt instanceof IdleStateEvent){
IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
if(idleStateEvent.state() == IdleState.WRITER_IDLE){
if(currentTime < 3){
System.out.println("currentTime : "+ currentTime);
currentTime++;
ctx.writeAndFlush(HEARTBEAT_SEQUENCE.duplicate());
}
}
}
super.userEventTriggered(ctx, evt);
}
HEARTBEAT_SEQUENCE.duplicate()
复制当前对象,复制后的对象与前对象共享缓冲区,且维护自己的独立索引
结果
- server
connect!
QUERY TIME ORDER
Heartbeat
recv Heartbeat!
Heartbeat
recv Heartbeat!
Heartbeat
recv Heartbeat!
1
2
3
close
disconnected!
- client
Send firstSendMsg!
Client read!
Now is :hello
EventTriggered TIME : Fri Dec 22 22:54:36 CST 2017
currentTime : 0
Client read!
Now is :has read message from server
EventTriggered TIME : Fri Dec 22 22:54:40 CST 2017
currentTime : 1
Client read!
Now is :has read message from server
EventTriggered TIME : Fri Dec 22 22:54:44 CST 2017
currentTime : 2
Client read!
Now is :has read message from server
EventTriggered TIME : Fri Dec 22 22:54:48 CST 2017
EventTriggered TIME : Fri Dec 22 22:54:52 CST 2017
EventTriggered TIME : Fri Dec 22 22:54:56 CST 2017
get : has read message from server
Relase group!
其他
- 设置attr
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.channel().attr(AttributeKey.valueOf("attrTest")).set(msg);
//...
super.channelRead(ctx, msg);
}
public class NettyClient {
public static void main(String[] args) {
//...
try {
ChannelFuture connectFuture = b.connect(new InetSocketAddress("127.0.0.1", 8001)).sync();
connectFuture.channel().closeFuture().sync();
Object res = connectFuture.channel().attr(AttributeKey.valueOf("attrTest")).get();
System.out.println("get : " + res.toString());
} catch (InterruptedException e) {
//...
} finally {
//...
}
}
}
- ctx.write 和ctx.channel.write()
Any difference between ctx.write() and ctx.channel().write() in netty?
Channel.write() 和 ChannelHandlerContext.write() 的区别