Netty5.0 实现心跳包

这是一个netty自带的echo案例,添加了心跳包的设置而已,关键代码如下:

/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package io.netty.example.echo;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.timeout.IdleStateHandler;

/**
 * Echoes back any received data from a client.
 */
public final class EchoServer {

	static final boolean SSL = System.getProperty("ssl") != null;
	static final int PORT = Integer
			.parseInt(System.getProperty("port", "8007"));

	public static void main(String[] args) throws Exception {
		// Configure SSL.
		final SslContext sslCtx;
		if (SSL) {
			SelfSignedCertificate ssc = new SelfSignedCertificate();
			sslCtx = SslContext.newServerContext(ssc.certificate(),
					ssc.privateKey());
		} else {
			sslCtx = null;
		}

		// 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 ChannelInitializer<SocketChannel>() {
						@Override
						public void initChannel(SocketChannel ch)
								throws Exception {
							ChannelPipeline p = ch.pipeline();
							if (sslCtx != null) {

								p.addLast(sslCtx.newHandler(ch.alloc()));
							}
							// p.addLast(new LoggingHandler(LogLevel.INFO));
							<span style="color:#FF0000;">p.addLast("idleStateHandler", new IdleStateHandler(10, 5, 0));
					                p.addLast("myHandler", new MyHandler());
							p.addLast(new EchoServerHandler());</span>
						}
					});

			// 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();
		}
	}
}
package io.netty.example.echo;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

/**
 * @Project : netty
 * @Package : io.netty.example.echo
 * @Class : MyHandler
 * @Company 广州讯动网络科技有限公司
 * @Author : 蔡文锋
 * @DateTime:2015年4月21日 下午11:15:47
 * @Blog:http://blog.csdn.net/caiwenfeng_for_23
 * @Description : {
 *  Handler should handle the IdleStateEvent triggered by IdleStateHandler.
 * }
 *
 */
public class MyHandler extends ChannelHandlerAdapter {
	@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();
				System.out.println("READER_IDLE 读超时");
			} else if (e.state() == IdleState.WRITER_IDLE) {
				ByteBuf buff = ctx.alloc().buffer();
				buff.writeBytes("mayi test".getBytes());
				ctx.writeAndFlush(buff);
				System.out.println("WRITER_IDLE 写超时");
			}
		}
	}
}

首先添加了idleStateHandler用于监听链接idle,如果连接到达idle时间,这个handler会触发idleEvent,之后通过重写userEventTriggered方法,完成idle事件的处理。

可以用telnet进行测试:

telnet 127.0.0.1 8007

测试结果:

WRITER_IDLE 写超时

READER_IDLE 读超时

时间: 2024-10-12 20:08:22

Netty5.0 实现心跳包的相关文章

在后台主机中托管SignalR服务并广播心跳包

什么是后台主机 在之前的 Asp.NETCore 轻松学系列中,曾经介绍过一个轻量级服务主机 IHostedService ,利用 IHostedService 可以轻松的实现一个系统级别的后台服务,该服务跟随系统启动和停止:同时,其使用异步加载和兼容注入的特性,可以很好的实现业务的扩展和隔离. IHostedService 有一个默认的实现基类 Microsoft.Extensions.Hosting.BackgroundService,我们仅需要继承 BackgroundService 即可

TCP连接探测中的Keepalive 和心跳包

采用TCP连接的C/S模式软件,连接的双方在连接空闲状态时,如果任意一方意外崩溃.当机.网线断开或路由器故障,另一方无法得知TCP连接已经失效,除非继续在此连接上发送数据导致错误返回.很多时候,这不是我们需要的.我们希望服务器端和客户端都能及时有效地检测到连接失效,然后优雅地完成一些清理工作并把错误报告给用户. 如何及时有效地检测到一方的非正常断开,一直有两种技术可以运用.一种是由TCP协议层实现的Keepalive,另一种是由应用层自己实现的心跳包. TCP默认并不开启Keepalive功能,

delphi datasnap 心跳包

为了能让我们的服务程序更加稳定,有些细节问题必须解决.就如上一讲中提到的客户端拔掉网线,造成服务器上TCP变成死连接,如果死连接数量过多,对服务器能长期稳定运行是一个巨大的威胁.另外,经过测试,如果服务器上有TCP死连接,那么服务程序连接数据库,也会产生那个一个死连接.这样的话,给数据库服务器也造成威胁.所以,服务器程序编写的好坏,直接影响系统的稳定性!如何解决TCP死连接的问题,有多种方法,其中最有效的就是心跳包技术.我们在DSServer的OnConnect事件中加入心跳包代码 uses I

Signalr 实现心跳包

项目分析: 一个实时的IM坐席系统,客户端和坐席使用IM通信,客户端使用android和ios的app,坐席使用web. web端可以保留自己的登录状态,但为防止意外情况的发生(如浏览器异常关闭,断网,断电),对坐席的实时在线状态造成影响,我们在后台跑一个服务,实时向每个坐席发送一个心跳包,当坐席的状态是在线,但是又不能接收到服务端的心跳包的时候,认为该坐席已经被异常下线. 实时通信Signalr 使用中发现signalr的服务端必须需要 .net frameword4.5及以上版本,对sign

[转] Socket心跳包异常检测的C语言实现,服务器与客户端代码案例

转载自:zxh2075的专栏 在Socket心跳机制中,心跳包可以由服务器发送给客户端,也可以由客户端发送给服务器,不过比较起来,前者开销可能较大.本文实现的是由客户端给服务器发送心跳包,服务器不必返回应答包,而是通过判断客户在线会话记录中的计数标志值来实现心跳异常的检测,以此决定客户端是否已经断开连接以及删除其在线会话记录. 基本思路: ①客户端定时给服务器发送心跳包(案例中定时时间为3秒): ②服务器创建一个心跳检测的线程,线程中每隔3秒对用户在线会话记录中的计数器进行加1操作(初始值为0)

长连接和心跳包

第一种设置:通过设置socket的keepalive属性#include    "/usr/include/linux/tcp.h"#include "/usr/include/linux/socket.h"////KeepAlive实现,单位秒//下面代码要求有ACE,如果没有包含ACE,则请把用到的ACE函数改成linux相应的接口int keepAlive = 1;//设定KeepAliveint keepIdle = 5;//开始首次KeepAlive探测前

心跳包 WPF Unity 数据库搭建

1.心跳包如何发送: 主要是客户机发送给服务器,服务器接收到后,再回复. //之前做的项目,WPF与U3D进行通信,WPF端是处于监听端,而U3D属于客户端,不断的发心跳包给WPF //WPF端代码如下: //嵌入U3D窗口 void initU3D() { //将Exehost 控件添加到 Winformhost控件中 if (UserData.enableEmbU3d) { ExeHost exehost = new ExeHost(); //formview.formHost.Child

心跳包机制原理

心跳包的发送,通常有两种技术 方法1:应用层自己实现的心跳包 由应用程序自己发送心跳包来检测连接是否正常,大致的方法是:服务器在一个 Timer事件中定时 向客户端发送一个短小精悍的数据包,然后启动一个低级别的线程,在该线程中不断检测客户端的回应, 如果在一定时间内没有收到客户端的回应,即认为客户端已经掉线:同样,如果客户端在一定时间内没 有收到服务器的心跳包,则认为连接不可用. 方法2:TCP的KeepAlive保活机制 因为要考虑到一个服务器通常会连接多个客户端,因此由用户在应用层自己实现心

loadrunner使用socket协议来实现客户端对服务器产生压力实例。(通过发送心跳包,达到连接多个客户端的目的)

#include "lrs.h" vuser_init(){ char *ip; int handler; //编写获取LR分配的Vuser IP函数,将IP保存在ip变量中. ip=lr_get_vuser_ip(); if(ip) lr_vuser_status_message("the ip address is %s:",ip); else lr_vuser_status_message("IP spooler disabled"); /