一、前言

踏踏实实,动手去做,talk is cheap, show me the code。先介绍下基础知识,然后做个心跳机制的Demo。

二、连接

长连接:在整个通讯过程,客户端和服务端只用一个Socket对象,长期保持Socket的连接;短连接:每次请求,都新建一个Socket,处理完一个请求就直接关闭掉Socket。所以,其实区分二者就是:整个客户和服务端的通讯过程是利用一个Socket还是多个Socket进行的。一般,长连接多用于数据发送频繁,点对点的通讯。因为TCP连接都需要握手,这很花费时间,有时建立连接的时间有可能比业务传输的时间要多。

客户端不主动断开连接,并不是说连接就不会断。比如:客户端突然断电、网线故障、空闲的Socket被防火墙自动关闭、系统崩溃等,服务端无法检测到连接的断开,因此需要对长连接进行管理。

保活的两种方式:

①TCP协议自带的keep-alive功能

★系统内核自动替上层做好

★内核层面计时器相比上册应用更高效

★数据包更紧凑,数据量更小

★默认的心跳时间是2小时,依赖操作系统实现不够灵活

②应用层的keep-alive,一般叫做心跳包机制

(TCP长连接中,客户端和服务端定时向对方发送数据包通知自己还在线,保证连接有效性的机制)

★完全使用业务层面的心跳保活机制

★更大灵活性,可以自己控制检测的参数,如检测的时间间隔、检测的方式等

★不依赖协议,心跳包同时适用于TCP和UDP

因此如果你们能确定更换协议的可能性非常小, 同时只是需要检活的功能, 那么用协议自带的就可以了, 使用简单而且高效。

三、Netty 心跳连接

1.基于 IdleStateHandler

首先我们要知道,在服务器和客户端之间,一段时间内没有数据交互时,即处于Idle状态。下面是通过Netty IdleStateHandler来实现心跳机制。

使用方法:

(code摘自Netty api 文档  https://netty.io/4.0/api/io/netty/handler/timeout/IdleStateHandler.html )

  public class MyChannelInitializer extends ChannelInitializer<Channel> {
@Override
public void initChannel(Channel channel) {
channel.pipeline().addLast("idleStateHandler", new IdleStateHandler(60, 30, 0));
// IdleStateHandler的构造方法有三个参数,监控读、监控写、监控读与写、触发心跳机制的时间间隔(单位,秒)
// 0 表示 disable
channel.pipeline().addLast("myHandler", new MyHandler());
}
} // Handler should handle the IdleStateEvent triggered by IdleStateHandler.
public class MyHandler extends ChannelDuplexHandler {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent e = (IdleStateEvent) evt;
if (e.state() == IdleState.READER_IDLE) {
ctx.close();
} else if (e.state() == IdleState.WRITER_IDLE) {
ctx.writeAndFlush(new PingMessage());
}
}
}
} ServerBootstrap bootstrap = ...;
...
bootstrap.childHandler(new MyChannelInitializer());
...

2.基于keep-alive

分别开启keep-alive功能即可

服务端:

b.group(group).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100)
.childOption(ChannelOption.SO_KEEPALIVE, true).handler(new LoggingHandler(LogLevel.INFO))
.localAddress(new InetSocketAddress(port)).childHandler(new ChannelInitializer<SocketChannel>() {

客户端:

bootstrap.group(group).channel(NioSocketChannel.class).option(ChannelOption.SO_KEEPALIVE, true)
.remoteAddress(new InetSocketAddress(host, port)).handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel channel) throws Exception {
channel.pipeline().addLast(new EchoClientHandler());
}
});

参考资料:

https://www.cnblogs.com/my_life/articles/4045696.html

https://blog.csdn.net/u013967175/article/details/78591810

https://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/

https://blog.csdn.net/linuu/article/details/51404264

连接管理 与 Netty 心跳机制的更多相关文章

  1. 一个Socket连接管理池(心跳机制)

    一个Socket连接管理池(心跳机制) http://cuisuqiang.iteye.com/blog/1489661

  2. 《即时消息技术剖析与实战》学习笔记8——IM系统如何保证长连接的可用性:心跳机制

    假设有以下突发意外情况: 用户进入信号不好的地方,手机没有网络信号了 上网的路由器突然掉线了 这个时候,比如微信发消息,消息就会转圈圈,甚至变成红色叹号-- 上面情况都会导致"长连接&quo ...

  3. NETTY 心跳机制

    最近工作比较忙,但闲暇之余还是看了阿里的冯家春(fengjiachun)的github上的开源代码Jupiter,写的RPC框架让我感叹人外有人,废话不多说,下面的代码全部截取自Jupiter,写了一 ...

  4. netty心跳机制测试

    netty中有比较完善的心跳机制,(在基础server版本基础上[netty基础--基本收发])添加少量代码即可实现对心跳的监测和处理. 1 server端channel中加入心跳处理机制 // Id ...

  5. Netty心跳机制

    一.概念介绍网络中的接收和发送数据都是使用操作系统中的SOCKET进行实现.但是如果此套接字已经断开,那发送数据和接收数据的时候就一定会有问题.可是如何判断这个套接字是否还可以使用呢?这个就需要在系统 ...

  6. netty心跳机制和断线重连(四)

    心跳是为了保证客户端和服务端的通信可用.因为各种原因客户端和服务端不能及时响应和接收信息.比如网络断开,停电 或者是客户端/服务端 高负载. 所以每隔一段时间 客户端发送心跳包到客户端  服务端做出心 ...

  7. netty心跳机制解决

    直接看别个的源码:https://blog.csdn.net/xt8469/article/details/84827443>>https://blog.csdn.net/xt8469/a ...

  8. Netty实现心跳机制

    netty心跳机制示例,使用Netty实现心跳机制,使用netty4,IdleStateHandler 实现.Netty心跳机制,netty心跳检测,netty,心跳 本文假设你已经了解了Netty的 ...

  9. Netty(六):Netty中的连接管理(心跳机制和定时断线重连)

    何为心跳 顾名思义, 所谓心跳, 即在TCP长连接中, 客户端和服务器之间定期发送的一种特殊的数据包, 通知对方自己还在线, 以确保 TCP 连接的有效性. 为什么需要心跳 因为网络的不可靠性, 有可 ...

随机推荐

  1. AOP面向切面编程JAVA动态代理实现用户权限管理(实现篇)

    java动态代理机制的功能十分强大,使用动态代理技术能够有效的降低应用中各个对象之间的耦合紧密程度,提高开发的效率以及程序的可维护性,事实上Spring AOP就是建立在Java动态代理的基础之上.其 ...

  2. Git通过密钥对远程仓库上传和更新详细操作

    1,先到ssh中ls查看之前本地生成的公钥和私钥,然后将别人的密钥替换掉自己的密钥,这里我把别人的密钥放在d:/desktop/id_rsa 中,利用cp /D/Desktop/id_rsa  id_ ...

  3. spring cloud使用Feign做消费端时的eureka.client.registerWithEureka/eureka.client.fetchRegistry是否配置的问题

    记录一下今天工作中的一个小失误. 今天用Feign搭建服务消费者的时候,考虑消费者不需要再提供服务给其他服务,所以不需要注册到注册中心(eureka)中.结果把registerWithEureka和f ...

  4. FUJI 富士 富仕 串口 N500I N700I 连接

    本人丰富的硬件连接经验, 1.出售富士生化设备N500I, N700I 接入,C#代码demo,  可连接机器验证,验证后付款2. 提供宠物行业富士生化设备N500I, N700I型号接入软件技术支持 ...

  5. Hadoop 搭建集群的步骤

    1.安装jdk,配置环境变量 root@localhost java]# vi /etc/profile 在profile中添加如下内容: #set java environmentexport  J ...

  6. caog

    import pandas as pd#匹配可发库存1. import oslst=os.listdir(r'E:\每日必做\琪琪小象库存')lst1=[]for i in lst: if i[:2] ...

  7. Python 查看线程的进程id

    import os from threading import Thread # from multiprocessing import Process def f1(n): print('1号',o ...

  8. Applets的分析

    一.有关Java Applet的基础 1.JavaApplet就是用Java语言编写的小应用程序,可以直接嵌入到网页中,并能够产生特殊的效果.包含Applet的网页被称为Java-powered页,可 ...

  9. phpexcel 使用说明

    下面是总结的几个使用方法 include 'PHPExcel.php'; include 'PHPExcel/Writer/Excel2007.php'; //或者include 'PHPExcel/ ...

  10. 命令行执行python模块时提示ImportError: No module named xxx

    在pycharm中运行python文件没有问题,切换到cmd中是提示:ImportError: No module named xxx 原因: pycharm在运行时会把当前工程的所有文件夹路径都作为 ...