日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

netty系列之:自动重连

發布時間:2024/2/28 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 netty系列之:自动重连 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 簡介
  • 使用netty建立連接
  • 自動重連接的原理
  • 模擬自動重連
  • 總結

簡介

我們在使用客戶端和服務器端連接的過程中,可能會因為各種問題導致客戶端和服務器的連接發生中斷,遇到這種情況,一般情況下我們需要使用監控程序去監聽客戶端和服務器端的連接,如果第一時間發現連接斷開了,就需要手動去重連。比較麻煩,今天給大家介紹一種netty中自動重連的方式。

使用netty建立連接

要使用netty建立連接,首先需要啟動服務器,通常來說服務器通過使用ServerBootstrap來啟動服務器,如下所示:

// 綁定端口并啟動 ChannelFuture f = b.bind(PORT).sync();

對于客戶端來說,可以通過Bootstrap按如下的方式啟動:

// 連接服務器 ChannelFuture f = b.connect(HOST, PORT).sync();

自動重連接的原理

那么當客戶端和服務器端的連接斷了之后,如何自動重連呢?

對于客戶端來說,自動重連只需要再次調用Bootstrap的connect方法即可。現在的關鍵問題在于,如何找到重新調用connect的時機。

我們知道,不論server還是client,對于消息的處理都需要注冊專門處理消息的handler。

對于讀取消息來說,一般需要繼承ChannelInboundHandlerAdapter,在這個handler中定義了很多和channel生命周期有關的方法,我們可以從這些生命周期的方法入手。

一般來說客戶端和服務器連接的狀態是這的:

CHANNEL REGISTERED–》CHANNEL ACTIVE --》 READ --》READ COMPLETE --》 CHANNEL INACTIVE --》 CHANNEL UNREGISTERED

客戶端和服務器端的連接如果關閉的話,則會觸發CHANNEL INACTIVE 和 CHANNEL UNREGISTERED 兩個事件,這樣我們在客戶端重寫下面兩個方法,在方法中加入重連的邏輯即可。

@Overridepublic void channelInactive(final ChannelHandlerContext ctx) {println("連接斷開:" + ctx.channel().remoteAddress());}@Overridepublic void channelUnregistered(final ChannelHandlerContext ctx) throws Exception {println("sleep:" + ReconnectClient.RECONNECT_DELAY + 's');ctx.channel().eventLoop().schedule(() -> {println("重連接: " + ReconnectClient.HOST + ':' + ReconnectClient.PORT);ReconnectClient.connect();}, ReconnectClient.RECONNECT_DELAY, TimeUnit.SECONDS);}

在channelInactive方法中,我們只是打印了一些日志。主要邏輯在channelUnregistered方法中,在這個方法中我們首先通過ctx獲取到當前的channel,然后拿到channel中的eventLoop,然后調用它的schedule方法,在給定的時間后重新調用connect()方法。

connect()方法返回的是一個ChannelFuture,所以可以在ChannelFuture中添加一些listener用來監聽connect的執行狀態。

這里定義的connect方法如下:

static void connect() {bs.connect().addListener(future -> {if (future.cause() != null) {handler.startTime = -1;handler.println("建立連接失敗: " + future.cause());}});}

模擬自動重連

上一節我們已經知道怎么自動重連了,本小節將會對自動重連進行一個模擬。

這里要介紹一個類,叫做IdleStateHandler,從名字就可以看出來這個類是當 Channel 沒有做任何read, write操作的時候,就會觸發這個Idle的狀態。

表示Idle狀態的類叫做IdleStateEvent,Idle有6個狀態,分別是FIRST_READER_IDLE_STATE_EVENT,READER_IDLE_STATE_EVENT,FIRST_WRITER_IDLE_STATE_EVENT,WRITER_IDLE_STATE_EVENT,FIRST_ALL_IDLE_STATE_EVENT和ALL_IDLE_STATE_EVENT。

分別表示讀取狀態的IDLE,寫狀態的IDLE和讀寫狀態的IDLE。

這樣我們在client啟動的時候就可以加上IdleStateHandler,當client一段時間沒有讀取到server端發來的消息的時候,我們就調用ctx.close()將channel關閉,從而出發client端的重連操作。

bs.group(group).channel(NioSocketChannel.class).remoteAddress(HOST, PORT).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new IdleStateHandler(READ_TIMEOUT, 0, 0), handler);}});

IdleStateEvent是一個用戶出發的event,要捕獲到這個event,需要重寫userEventTriggered:

public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {if (!(evt instanceof IdleStateEvent)) {return;}IdleStateEvent e = (IdleStateEvent) evt;if (e.state() == IdleState.READER_IDLE) {// 在Idle狀態println("Idle狀態,關閉連接");ctx.close();}}

上面的例子中,我們捕獲了IdleStateEvent,并判斷如果IdleState的狀態是IdleState.READER_IDLE,那么就將channel關閉。

總結

本文我們介紹了重連的原理和用戶觸發的Event,希望大家能夠喜歡。

本文的例子可以參考:learn-netty4

本文已收錄于 http://www.flydean.com/09-netty-reconnect/

最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!

總結

以上是生活随笔為你收集整理的netty系列之:自动重连的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。