netty自定义消息实现心跳检测与重连

本文介绍了如何在Netty中自定义心跳检测和重连机制,特别是在客户端。利用IdleStateHandler来检测无数据交换的状态,并在超时后触发相应操作。详细代码包括自定义协议的解码器、编码器、服务端和客户端的实现,以及客户端的重连检测逻辑。通过运行示例,展示了服务端和客户端的交互,当服务端关闭时,客户端能进行有效的日志记录并尝试重连。

netty的心跳发送的重连,主要在client端。前面有关于自定义协议的demo:https://blog.youkuaiyun.com/zc_ad/article/details/83829620

其实客户端心跳发送用到的是IdleStateHandler,详细看代码你就会明白为什么。

 //处理空闲状态事件的处理器
pipeline.addLast(new IdleStateHandler(6,7,8, TimeUnit.SECONDS));

在IdleStateHandler中前三个参数分别是:

1.当在6秒内收到消息,触发IdleStateEvent事件。

2.当在7秒内没有发送消息,触发IdleStateEvent事件。

3.当在8内没有接收到数据且在8秒内没有发送数据,触发IdleStateEvent事件。

下面是实现的代码,代码量有点多....:

 

常量数据:

/**
 * Created by XiChuan on 2018-11-07.
 */
public class Constant {

    public static final int HEAD = 0x76;

    public static final String TYPE_PING = "PING";

    public static final String TYPE_MESSAGE = "MESSAGE";
}

自定义协议:

/**
 * Created by XiChuan on 2018-11-07.
 */

import java.util.Arrays;

/**
 * <pre>
 * 自己定义的协议
 *  数据包格式
 * +——----——+——-----——+——----——+
 * |协议开始标志|  消息类型长度  |  消息类型 |    数据长度   |   数据    |
 * +——----——+——-----——+——----——+
 * 1.协议开始标志head_data,为int类型的数据,16进制表示为0X76
 * 2.要传的协议类型长度(String的byte[]长度)
 * 3.要传的协议类型(String)
 * 4.传输数据的长度contentLength,int类型
 * 5.要传输的数据
 * </pre>
 */
public class MessageProtocol {
    /**
     * 消息的开头的信息标志
     */
    private int headData = Constant.HEAD;

    /**
     * 消息类型长度
     */
    private int typeLength;

    /**
     * 消息类型
     */
    private String type;

    /**
     * 消息的长度
     */
    private int contentLength;
    /**
     * 消息的内容
     */
    private byte[] content;

    /**
     * 用于初始化,SmartCarProtocol
     *
     * @param contentLength
     *            协议里面,消息数据的长度
     * @param content
     *            协议里面,消息的数据
     */
    public MessageProtocol(int typeLength,String type,int contentLength, byte[] content) {
        this.typeLength = typeLength;
        this.type = type;
        this.contentLength = contentLength;
        this.content = content;
    }

    public int getHeadData() {
        return headData;
    }

    public void setHeadData(int headData) {
        this.headData = headData;
    }

    public int getTypeLength() {
        return typeLength;
    }

    public void setTypeLength(int typeLength) {
        this.typeLength = typeLength;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getContentLength() {
        return contentLength;
    }

    public void setContentLength(int contentLength) {
        this.contentLength = contentLength;
    }

    public byte[] getContent() {
        return content;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "MessageProtocol " +
                "[head_data=" + headData
                +", typeLength="+typeLength
                +", type="+type
                + ", contentLength=" + contentLength
                + ", content=" + Arrays.toString(content) + "]";
    }
}

定义解码器:

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * Created by XiChuan on 2018-11-06.
 */


public class MessageProtocolDecoder extends ByteToMessageDecoder {

    /**
     * <pre>
     * 协议开始的标准head_data,int类型,占据4个字节.
     * 表示数据的长度contentLength,int类型,占据4个字节.
     * </pre>
     */
    public final int BASE_LENGTH = 4 + 4;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf buffer,
                          List<Object> out) throws Exception {
        // 可读长度必须大于基本长度
        //System.out.println("buff的可读长度是:"+buffer.readableBytes());
        if (buffer.readableBytes() >= BASE_LENGTH) {
            // 防止socket字节流攻击
            // 防止,客户端传来的数据过大
            // 因为,太大的数据,是不合理的
            if (buffer.readableBytes() > 2048) {
                buffer.skipBytes(buffer.readableBytes());
            }

            // 记录包头开始的index
            int beginReader;

            while (true) {
                // 获取包头开始的index
          
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值