Netty 超時機制及心跳程序?qū)崿F(xiàn)

本文介紹了 Netty 超時機制的原理,以及如何在連接閑置時發(fā)送一個心跳來維持連接。


Netty 超時機制的介紹

Netty 的超時類型 IdleState 主要分為:

ALL_IDLE : 一段時間內(nèi)沒有數(shù)據(jù)接收或者發(fā)送

READER_IDLE : 一段時間內(nèi)沒有數(shù)據(jù)接收

WRITER_IDLE : 一段時間內(nèi)沒有數(shù)據(jù)發(fā)送

在 Netty 的 timeout 包下,主要類有:

IdleStateEvent : 超時的事件

IdleStateHandler : 超時狀態(tài)處理

ReadTimeoutHandler : 讀超時狀態(tài)處理

WriteTimeoutHandler : 寫超時狀態(tài)處理

其中 IdleStateHandler 包含了讀\寫超時狀態(tài)處理,比如

private static final int READ_IDEL_TIME_OUT = 4; // 讀超時

private static final int WRITE_IDEL_TIME_OUT = 5;// 寫超時

private static final int ALL_IDEL_TIME_OUT = 7; // 所有超時

new IdleStateHandler(READ_IDEL_TIME_OUT,

WRITE_IDEL_TIME_OUT, ALL_IDEL_TIME_OUT, TimeUnit.SECONDS));

上述例子,在 IdleStateHandler 中定義了讀超時的時間是 4 秒, 寫超時的時間是 5 秒,其他所有的超時時間是 7 秒。

應(yīng)用 IdleStateHandler

既然 IdleStateHandler 包括了讀\寫超時狀態(tài)處理,那么很多時候 ReadTimeoutHandler 、 WriteTimeoutHandler 都可以不用使用。定義另一個名為 HeartbeatHandlerInitializer 的 ChannelInitializer :

public class HeartbeatHandlerInitializer extends ChannelInitializer {

private static final int READ_IDEL_TIME_OUT = 4; // 讀超時

private static final int WRITE_IDEL_TIME_OUT = 5;// 寫超時

private static final int ALL_IDEL_TIME_OUT = 7; // 所有超時

@Override

protected void initChannel(Channel ch) throws Exception {

ChannelPipeline pipeline = ch.pipeline();

pipeline.addLast(new IdleStateHandler(READ_IDEL_TIME_OUT,

WRITE_IDEL_TIME_OUT, ALL_IDEL_TIME_OUT, TimeUnit.SECONDS)); // 1

pipeline.addLast(new HeartbeatServerHandler()); // 2

}

}

使用了 IdleStateHandler ,分別設(shè)置了讀、寫超時的時間

定義了一個 HeartbeatServerHandler 處理器,用來處理超時時,發(fā)送心跳

定義了一個心跳處理器

public class HeartbeatServerHandler extends ChannelInboundHandlerAdapter {

// Return a unreleasable view on the given ByteBuf

// which will just ignore release and retain calls.

private static final ByteBuf HEARTBEAT_SEQUENCE = Unpooled

.unreleasableBuffer(Unpooled.copiedBuffer("Heartbeat",

CharsetUtil.UTF_8));? // 1

@Override

public void userEventTriggered(ChannelHandlerContext ctx, Object evt)

throws Exception {

if (evt instanceof IdleStateEvent) {? // 2

IdleStateEvent event = (IdleStateEvent) evt;

String type = "";

if (event.state() == IdleState.READER_IDLE) {

type = "read idle";

} else if (event.state() == IdleState.WRITER_IDLE) {

type = "write idle";

} else if (event.state() == IdleState.ALL_IDLE) {

type = "all idle";

}

ctx.writeAndFlush(HEARTBEAT_SEQUENCE.duplicate()).addListener(

ChannelFutureListener.CLOSE_ON_FAILURE);? // 3

System.out.println( ctx.channel().remoteAddress()+"超時類型:" + type);

} else {

super.userEventTriggered(ctx, evt);

}

}

}

定義了心跳時,要發(fā)送的內(nèi)容

判斷是否是 IdleStateEvent 事件,是則處理

將心跳內(nèi)容發(fā)送給客戶端


服務(wù)器

服務(wù)器代碼比較簡單,啟動后偵聽 8082 端口

public final class HeartbeatServer {

static final int PORT = 8082;

public static void main(String[] args) throws Exception {

// Configure the server.

EventLoopGroup bossGroup = new NioEventLoopGroup(1);

EventLoopGroup workerGroup = new NioEventLoopGroup();

try {

ServerBootstrap b = new ServerBootstrap();

b.group(bossGroup, workerGroup)

.channel(NioServerSocketChannel.class)

.option(ChannelOption.SO_BACKLOG, 100)

.handler(new LoggingHandler(LogLevel.INFO))

.childHandler(new HeartbeatHandlerInitializer());

// Start the server.

ChannelFuture f = b.bind(PORT).sync();

// Wait until the server socket is closed.

f.channel().closeFuture().sync();

} finally {

// Shut down all event loops to terminate all threads.

bossGroup.shutdownGracefully();

workerGroup.shutdownGracefully();

}

}

}


客戶端測試

客戶端用操作系統(tǒng)自帶的 Telnet 程序即可:

telnet 127.0.0.1 8082

20151106-heartbeat

源碼見https://github.com/waylau/netty-4-user-guide-demos中 heartbeat包

大家可以點擊加入群:【Java高級架構(gòu)進階群】:854180697

里面有Java高級大牛直播講解知識點 走的就是高端路線 (如果你想跳槽換工作 但是技術(shù)又不夠 或者工作上遇到了瓶頸 我這里有一個JAVA的免費直播課程 講的是高端的知識點基礎(chǔ)不好的誤入喲 只要你有1-5年的開發(fā)經(jīng)驗可以加群找我要課堂鏈接 注意:是免費的 沒有開發(fā)經(jīng)驗誤入哦)



寫在最后:歡迎留言討論。加關(guān)注,持續(xù)更新!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,991評論 19 139
  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,449評論 0 10
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,778評論 18 399
  • 俗話說:“遠親不如近鄰”,這話說的一點都沒錯。 就拿我現(xiàn)在的鄰居來說吧,我婆婆基本算的上他們家的半個家庭成員。 隔...
    耿耿廣州閱讀 217評論 0 0
  • 這個世界上或許沒有絕對的好與壞,對與錯,信與不信,值得與不值得,可惜不可惜。無論怎么樣時間依舊會和之前一樣默默流逝...
    喵兒總閱讀 826評論 2 0