LengthFieldBasedFrameDecoder 真实案例使用

package cn.com.abc.obddatacollect.net;

import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 *
 * @author 28338007@qq.com
 * 基于  LengthFieldBasedFrameDecoder   解码链初始化
 * @time 2019年12月5日
 */

@Component
public class LengthFieldServerHandlerInitializer extends ChannelInitializer<SocketChannel> {
    private static final Logger logger = LoggerFactory.getLogger(NetServer.class);

    @Value("${netty.sign-or-encrypt:4}")
    private int signOrEncrypt;     //1:验签并加密,2:只验签不加密,3:只加密不验签

    @Value("${netty.agreement-type:gb}")
    private String agreementType;    //协议类型:gb(国标),ht(私有)

    @Value("${netty.idle-count:20}")   //链路空闲次数(每次15秒)
    private int idleCount;

    @Value("${netty.send-rate:3}")
    private int sendRate ;          //设置发送频率,0:不限制,其他值为跳过所设值后才发送消息
    @Value("${netty.check-login:1}")
    private int checkLogin ;          //设置发送频率,0:不限制,其他值为跳过所设值后才发送消息

    private static final int MAX_FRAME_LENGTH=1024*512;    //最大包长度
    private static final int LENGTH_FIELD_OFFSET=22;                //长度字段在包中的位置
    private static final int LENGTH_FIELD_LENGTH=2;                //长度字段数占的字节数
    //添加到长度字段的补偿值,本系统报文,最后有一个字节的校验码,所以这里的补偿值是1;
    // LENGTH_ADJUSTMENT = 整个数据包长度-  LENGTH_FIELD_OFFSET - LENGTH_FIELD_LENGTH - 数据段的长度值
    //本协议中最后一个字节的校验码没有包含在 LENGTH_FIELD_OFFSET+LENGTH_FIELD_LENGTH + 数据段的长度值 中,所以这个地方的值为1
    private static final int LENGTH_ADJUSTMENT=1;
    private static final int INITIAL_BYTES_TO_STRIP=2;             //从解码帧中头部去除的字节数

    @Override
    protected void initChannel(SocketChannel ch)  {
        ChannelInboundHandlerAdapter businessHandler;
        switch (signOrEncrypt){
            case Constants.SIGN_AND_ENCRYPT:
                businessHandler = new LengthFieldDecodeWithSignatureAndEncryptHandler(idleCount,agreementType,sendRate,checkLogin);
                break;
            case Constants.ENCRYPT_ONLY:
                businessHandler = new LengthFieldDecodeWithEncryptHandler(idleCount,agreementType,sendRate,checkLogin);
                break;
            case Constants.NO_SIGN_NO_ENCRYPT:
                businessHandler = new LengthFieldDecodeHandler(idleCount,agreementType,sendRate,checkLogin);
                break;
             default:
                 businessHandler = new LengthFieldDecodeWithSignatureHandler(idleCount,agreementType,sendRate,checkLogin);
                 break;
        }
        ch.pipeline()
                  .addLast(
                        new ExceptionHandler(),
                        //每隔15秒的时间内如果没有接受到任何的read事件的话,则会触发userEventTriggered事件,并指定IdleState的类型为READER_IDLE
                        new IdleStateHandler(15, 0, 0, TimeUnit.SECONDS),
                        //根据报结构中指定数据长度的报解析
                        new LengthFieldBasedFrameDecoder(MAX_FRAME_LENGTH,LENGTH_FIELD_OFFSET,LENGTH_FIELD_LENGTH,LENGTH_ADJUSTMENT,INITIAL_BYTES_TO_STRIP),
                        //new LengthFieldPrepender(2),
                        //new LengthFieldDecodeWithEncryptHandler(idleCount)
                        businessHandler
                );
       }


    static final class ExceptionHandler extends ChannelDuplexHandler {
        @Override
        public void close(ChannelHandlerContext ctx, ChannelPromise promise)
                throws Exception {
            super.close(ctx, promise);
        }
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            final String remoteAddress = ctx.channel().remoteAddress().toString();
            ctx.flush();
            ctx.close();
            logger.error("客户端强制断开了一个连接 {}", remoteAddress);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
       在Java界,Netty无疑是开发网络应用的拿手菜。你不需要太多关注复杂的NIO模型和底层网络的细节,使用其丰富的接口,可以很容易的实现复杂的通讯功能。 本课程准备的十二个实例,按照由简单到复杂的学习路线,让你能够快速学习如何利用Netty来开发网络通信应用。                每个实例简洁、清爽、实用,重点在“用”上,即培训大家如何熟练的使用Netty解决实际问题,抛弃以往边讲应用边分析源码的培训模式所带来的“高不成低不就”情况,在已经能够熟练使用、并且清楚开发流程的基础上再去分析源码就会思路清晰、事半功倍。        本套课程的十二个实例,各自独立,同时又层层递进,每个实例都是针对典型的实际应用场景,学了马上就能应用到实际项目中去。 学习好Netty 总有一个理由给你惊喜!! 一、应用场景        Netty已经众多领域得到大规模应用,这些领域包括:物联网领域、互联网领域、电信领域、大数据领域、游戏行业、企业应用、银行证券金融领域、。。。  二、技术深度        多款开源框架中应用了Netty,如阿里分布式服务框架 Dubbo 的 RPC 框架、淘宝的消息中间件 R0cketMQ、Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架、开源集群运算框架 Spark、分布式计算框架 Storm、并发应用和分布式应用 Akka、。。。  三、就业前景         很多大厂在招聘高级/资深Java工程师时要求熟练学习、或熟悉Netty,下面只是简要列出,这个名单可以很长。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值