Netty03 | 源码 心跳

如何阅读源码

一段一段看

  • 断点
  • 打印日志
  • 看调用栈
  • 搜索

心跳

心跳其实就是一个普通的请求,特点数据简单,业务也简单。

心跳对于服务端来说,定时清除闲置会话inactive(netty5) channelclose(netty3)

心跳对客户端来说,用来检测会话是否断开,是否重连! 用来检测网络延时!

心跳具体实现

基于 netty3

server

server 当检测到时 client 心跳包时,根据自定义心跳协议,回传给 Client 信息。

  1. 学习idleStateHandler
    用来检测会话状态
    需要用到 SimpleChannelHandler

    SimpleChannelHandler

    idleStateAwareChannelHandler

    HelloHandler extends idleStateAwareChannelHandler implements ChannelHandler
    HelloHandler extends SimpleChannelHandler

@Override
	public void handleUpstream(final ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
		if (e instanceof IdleStateEvent) {
			if(((IdleStateEvent)e).getState() == IdleState.ALL_IDLE){
				System.out.println("提玩家下线");
				//关闭会话,踢玩家下线
				ChannelFuture write = ctx.getChannel().write("time out, you will close");
				write.addListener(new ChannelFutureListener() {
					
					@Override
					public void operationComplete(ChannelFuture future) throws Exception {
						 ctx.getChannel().close();
					}
				});
			}
		} else {
			super.handleUpstream(ctx, e);
		}
	}
  1. 设置超时状态
    读超时:
    写超时:
    读写超时:
    如果有 client 有读写操作,将重置此时间。
  2. 超时时的业务处理选择
    • 如果超时 server 清除此 channel
    • 发消息给此 channel
    • channel.close
      到此 client 显示将丢失连接

Client

自定义消息,定时发送 心跳包,传递基本信息。

if channelDisconnected channelClosed
重连

状态:
SimpleChannelHandler

下面只是简要代码

package com.heart.client;

import com.heart.MyDate;
import org.jboss.netty.channel.*;
import org.jboss.netty.handler.timeout.IdleState;
import org.jboss.netty.handler.timeout.IdleStateEvent;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Author: Jie
 * @Date: 2019/3/18 16:19
 * @Function :
 */
public class ClientHandler extends SimpleChannelHandler {
    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        super.messageReceived(ctx, e);
        System.out.println("客户端 接收到消息:"+e.getMessage());
    }

    @Override
    public void handleUpstream(final ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
        if (e instanceof IdleStateEvent) {
            String time =MyDate.getNowDate();
            if(((IdleStateEvent)e).getState()== IdleState.READER_IDLE){
                System.out.println(time+ " read Idle "  );
            }else if(((IdleStateEvent)e).getState()== IdleState.WRITER_IDLE){
                System.out.println(time + " write Idle");
            }else if(((IdleStateEvent)e).getState() == IdleState.ALL_IDLE){
                System.out.println(time+"提玩家下线");
                //关闭会话,踢玩家下线
                ChannelFuture write = ctx.getChannel().write("time out, you will close");
                write.addListener(new ChannelFutureListener() {

                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        ctx.getChannel().close();
                    }
                });
            }
        } else {
            super.handleUpstream(ctx, e);
        }
    }

    @Override
    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        super.channelConnected(ctx, e);
        System.out.println("channelConnected");
    }

    //只有当本地客户机已经成功的与远程主机建立连接(connected)时,连接断开的时候才会触发channelDisconnected事件
    @Override
    public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        super.channelDisconnected(ctx, e);
        System.out.println("channelDisconnected");

    }

    @Override
    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        super.channelClosed(ctx, e);
        System.out.println("channelClosed");
    }
}

tryReconnect 没贴出,需要注意的点:

  • 注意包大小
    只应包含基本的必要信息。
  • 判断网络
    receiver接收当前网络变化,
    当网络可用时重连
  • 看当前业务是否需要重连
    eg. 机器升级中,不需要重连推迟重连。
    登录中,不需要重连。
  • close 当前连接
  • 防止多次重连造成并发与开销
  • Pipeline中 keepAlive、tcpNoDelay true

备注: 之前采用netty(3.6.6-fianl)支持通道检测IdleStateHandler,发现有些机型
手机休眠之后IdleStateHandler 定时器HashedWheelTimer可能存在被系统停止关闭的现象
所以采用AlarmManager 进行心跳的检测
登陆之后就开始触发心跳检测 【仅仅是在线,重练就会取消的】
退出reset 会释放alarmManager 资源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值