电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Java Netty實現心跳機制過程解析

瀏覽:118日期:2022-09-05 08:30:27

netty心跳機制示例,使用Netty實現心跳機制,使用netty4,IdleStateHandler 實現。Netty心跳機制,netty心跳檢測,netty,心跳

本文假設你已經了解了Netty的使用,或者至少寫過netty的helloworld,知道了netty的基本使用。我們知道使用netty的時候,大多數的東西都與Handler有關,我們的業務邏輯基本都是在Handler中實現的。Netty中自帶了一個IdleStateHandler 可以用來實現心跳檢測。

心跳檢測的邏輯

本文中我們將要實現的心跳檢測邏輯是這樣的:服務端啟動后,等待客戶端連接,客戶端連接之后,向服務端發送消息。如果客戶端在“干活”那么服務端必定會收到數據,如果客戶端“閑下來了”那么服務端就接收不到這個客戶端的消息,既然客戶端閑下來了,不干事,那么何必浪費連接資源呢?所以服務端檢測到一定時間內客戶端不活躍的時候,將客戶端連接關閉。本文要實現的邏輯步驟為:

啟動服務端,啟動客戶端 客戶端向服務端發送'I am alive',并sleep隨機時間,用來模擬空閑。 服務端接收客戶端消息,并返回'copy that',客戶端空閑時 計數+1. 服務端客戶端繼續通信 服務端檢測客戶端空閑太多,關閉連接。客戶端發現連接關閉了,就退出了。

有了這個思路,我們先來編寫服務端。

心跳檢測服務端代碼

public class HeartBeatServer { int port ; public HeartBeatServer(int port){ this.port = port; } public void start(){ ServerBootstrap bootstrap = new ServerBootstrap(); EventLoopGroup boss = new NioEventLoopGroup(); EventLoopGroup worker = new NioEventLoopGroup(); try{ bootstrap.group(boss,worker) .handler(new LoggingHandler(LogLevel.INFO)) .channel(NioServerSocketChannel.class) .childHandler(new HeartBeatInitializer()); ChannelFuture future = bootstrap.bind(port).sync(); future.channel().closeFuture().sync(); }catch(Exception e){ e.printStackTrace(); }finally { worker.shutdownGracefully(); boss.shutdownGracefully(); } } public static void main(String[] args) throws Exception { HeartBeatServer server = new HeartBeatServer(8090); server.start(); }}

熟悉netty的同志,對于上面的模板一樣的代碼一定是在熟悉不過了。啥都不用看,只需要看childHandler(new HeartBeatInitializer()) 這一句。HeartBeatInitializer就是一個ChannelInitializer顧名思義,他就是在初始化channel的時做一些事情。我們所需要開發的業務邏輯Handler就是在這里添加的。其代碼如下:

public class HeartBeatInitializer extends ChannelInitializer<Channel> { @Override protected void initChannel(Channel channel) throws Exception { ChannelPipeline pipeline = channel.pipeline(); pipeline.addLast('decoder', new StringDecoder()); pipeline.addLast('encoder', new StringEncoder()); pipeline.addLast(new IdleStateHandler(2,2,2, TimeUnit.SECONDS)); pipeline.addLast(new HeartBeatHandler()); }}

代碼很簡單,我們先添加了StringDecoder,和StringEncoder。這兩個其實就是編解碼用的,下面的IdleStateHandler才是本次心跳的核心組件。我們可以看到IdleStateHandler的構造函數中接收了4個參數,其定義如下:

public IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime, TimeUnit unit);

三個空閑時間參數,以及時間參數的格式。我們的例子中設置的是2,2,2,意思就是客戶端2秒沒有讀/寫,這個超時時間就會被觸發。超時事件觸發就需要我們來處理了,這就是上的HeartBeatInitializer中最后一行的HeartBeatHandler所做的事情。代碼如下:

public class HeartBeatHandler extends SimpleChannelInboundHandler<String> { int readIdleTimes = 0; @Override protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception { System.out.println(' ====== > [server] message received : ' + s); if('I am alive'.equals(s)){ ctx.channel().writeAndFlush('copy that'); }else { System.out.println(' 其他信息處理 ... '); } } @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { IdleStateEvent event = (IdleStateEvent)evt; String eventType = null; switch (event.state()){ case READER_IDLE:eventType = '讀空閑';readIdleTimes ++; // 讀空閑的計數加1break; case WRITER_IDLE:eventType = '寫空閑';// 不處理break; case ALL_IDLE:eventType ='讀寫空閑';// 不處理break; } System.out.println(ctx.channel().remoteAddress() + '超時事件:' +eventType); if(readIdleTimes > 3){ System.out.println(' [server]讀空閑超過3次,關閉連接'); ctx.channel().writeAndFlush('you are out'); ctx.channel().close(); } } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.err.println('=== ' + ctx.channel().remoteAddress() + ' is active ==='); }}

至此,我們的服務端寫好了。

心跳檢測客戶端代碼

netty的api設計使得編碼的模式非常具有通用性,所以客戶端代碼和服務端的代碼幾乎一樣:啟動client端的代碼幾乎一樣,也需要一個ChannelInitializer,也需要Handler。改動的地方很少,因此本文不對客戶端代碼進行詳細解釋。下面給出client端的完整代碼:

public class HeartBeatClient { int port; Channel channel; Random random ; public HeartBeatClient(int port){ this.port = port; random = new Random(); } public static void main(String[] args) throws Exception{ HeartBeatClient client = new HeartBeatClient(8090); client.start(); } public void start() { EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); try{ Bootstrap bootstrap = new Bootstrap(); bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class) .handler(new HeartBeatClientInitializer()); connect(bootstrap,port); String text = 'I am alive'; while (channel.isActive()){sendMsg(text); } }catch(Exception e){ // do something }finally { eventLoopGroup.shutdownGracefully(); } } public void connect(Bootstrap bootstrap,int port) throws Exception{ channel = bootstrap.connect('localhost',8090).sync().channel(); } public void sendMsg(String text) throws Exception{ int num = random.nextInt(10); Thread.sleep(num * 1000); channel.writeAndFlush(text); } static class HeartBeatClientInitializer extends ChannelInitializer<Channel> { @Override protected void initChannel(Channel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast('decoder', new StringDecoder()); pipeline.addLast('encoder', new StringEncoder()); pipeline.addLast(new HeartBeatClientHandler()); } } static class HeartBeatClientHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println(' client received :' +msg); if(msg!= null && msg.equals('you are out')) {System.out.println(' server closed connection , so client will close too');ctx.channel().closeFuture(); } } }}

運行代碼

在上面的代碼寫好之后,我們先啟動服務端,然后在啟動客戶端。運行日志如下:

server端:

=== /127.0.0.1:57700 is active === ====== > [server] message received : I am alive ====== > [server] message received : I am alive/127.0.0.1:57700超時事件:寫空閑/127.0.0.1:57700超時事件:讀空閑/127.0.0.1:57700超時事件:讀寫空閑/127.0.0.1:57700超時事件:寫空閑/127.0.0.1:57700超時事件:讀空閑/127.0.0.1:57700超時事件:讀寫空閑/127.0.0.1:57700超時事件:寫空閑 ====== > [server] message received : I am alive/127.0.0.1:57700超時事件:寫空閑/127.0.0.1:57700超時事件:讀寫空閑/127.0.0.1:57700超時事件:讀空閑/127.0.0.1:57700超時事件:寫空閑/127.0.0.1:57700超時事件:讀寫空閑/127.0.0.1:57700超時事件:讀空閑 [server]讀空閑超過3次,關閉連接

client端:

client sent msg and sleep 2 client received :copy that client received :copy that client sent msg and sleep 6 client sent msg and sleep 6 client received :copy that client received :you are out server closed connection , so client will close tooProcess finished with exit code 0

通過上面的運行日志,我們可以看到:

1.客戶端在與服務器成功建立之后,發送了3次’I am alive’,服務端也回應了3次:’copy that’

2.由于客戶端消極怠工,超時了多次,服務端關閉了鏈接。

3.客戶端知道服務端拋棄自己之后,也關閉了連接,程序退出。

以上簡單了演示了一下,netty的心跳機制,其實主要就是使用了IdleStateHandler。源碼下載

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
主站蜘蛛池模板: 物流之家新闻网-最新物流新闻|物流资讯|物流政策|物流网-匡匡奈斯物流科技 | 流量卡中心-流量卡套餐查询系统_移动电信联通流量卡套餐大全 | 光谱仪_积分球_分布光度计_灯具检测生产厂家_杭州松朗光电【官网】 | 安德建奇火花机-阿奇夏米尔慢走丝|高维|发那科-北京杰森柏汇 | 北京工业设计公司-产品外观设计-产品设计公司-千策良品工业设计 北京翻译公司-专业合同翻译-医学标书翻译收费标准-慕迪灵 | 烟台螺纹,烟台H型钢,烟台钢材,烟台角钢-烟台市正丰金属材料有限公司 | 硅胶布|电磁炉垫片|特氟龙胶带-江苏浩天复合材料有限公司 | 北京办公室装修,办公室设计,写字楼装修-北京金视觉装饰工程公司 北京成考网-北京成人高考网 | 定制异形重型钢格栅板/钢格板_定做踏步板/排水沟盖板_钢格栅板批发厂家-河北圣墨金属制品有限公司 | 盐水蒸发器,水洗盐设备,冷凝结晶切片机,转鼓切片机,絮凝剂加药系统-无锡瑞司恩机械有限公司 | 安徽净化板_合肥岩棉板厂家_玻镁板厂家_安徽科艺美洁净科技有限公司 | 猎头招聘_深圳猎头公司_知名猎头公司 | 食品无尘净化车间,食品罐装净化车间,净化车间配套风淋室-青岛旭恒洁净技术有限公司 | 环球周刊网| 量子管通环-自清洗过滤器-全自动反冲洗过滤器-北京罗伦过滤技术集团有限公司 | 深圳南财多媒体有限公司介绍 | 成都治疗尖锐湿疣比较好的医院-成都治疗尖锐湿疣那家医院好-成都西南皮肤病医院 | 开云(中国)Kaiyun·官方网站 - 登录入口 | led太阳能路灯厂家价格_风光互补庭院灯_农村市政工程路灯-中山华可路灯品牌 | 上海网站建设-上海网站制作-上海网站设计-上海做网站公司-咏熠软件 | 淄博不锈钢,淄博不锈钢管,淄博不锈钢板-山东振远合金科技有限公司 | 上海logo设计 | 立式_复合式_壁挂式智能化电伴热洗眼器-上海达傲洗眼器生产厂家 理化生实验室设备,吊装实验室设备,顶装实验室设备,实验室成套设备厂家,校园功能室设备,智慧书法教室方案 - 东莞市惠森教学设备有限公司 | 成都顶呱呱信息技术有限公司-贷款_个人贷款_银行贷款在线申请 - 成都贷款公司 | H型钢切割机,相贯线切割机,数控钻床,数控平面钻,钢结构设备,槽钢切割机,角钢切割机,翻转机,拼焊矫一体机 | 低温柔性试验仪-土工布淤堵-沥青车辙试验仪-莱博特(天津)试验机有限公司 | 造价工程师网,考试时间查询,报名入口信息-网站首页 | Trimos测长机_测高仪_TESA_mahr,WYLER水平仪,PWB对刀仪-德瑞华测量技术(苏州)有限公司 | 上海小程序开发-上海小程序制作公司-上海网站建设-公众号开发运营-软件外包公司-咏熠科技 | 成都思迪机电技术研究所-四川成都思迪编码器 | 东莞螺丝|东莞螺丝厂|东莞不锈钢螺丝|东莞组合螺丝|东莞精密螺丝厂家-东莞利浩五金专业紧固件厂家 | 四川成都干燥设备_回转筒干燥机_脉冲除尘器_输送设备_热风炉_成都川工星科机电设备有限公司 | 春腾云财 - 为企业提供专业财税咨询、代理记账服务 | 卫生纸复卷机|抽纸机|卫生纸加工设备|做卫生纸机器|小型卫生纸加工需要什么设备|卫生纸机器设备多少钱一台|许昌恒源纸品机械有限公司 | 伸缩节_伸缩器_传力接头_伸缩接头_巩义市联通管道厂 | WF2户外三防照明配电箱-BXD8050防爆防腐配电箱-浙江沃川防爆电气有限公司 | 电动百叶窗,开窗器,电动遮阳百叶,电动开窗机生产厂家-徐州鑫友工控科技发展有限公司 | 防爆大气采样器-防爆粉尘采样器-金属粉尘及其化合物采样器-首页|盐城银河科技有限公司 | 【同风运车官网】一站式汽车托运服务平台,验车满意再付款 | 科昊仪器超纯水机系统-可成气相液氮罐-美菱超低温冰箱-西安昊兴生物科技有限公司 | 山东臭氧发生器,臭氧发生器厂家-山东瑞华环保设备 |