Netty网络框架在安卓端的使用介绍

Netty的介绍

介绍:

Netty 是JBoss提供的一个java开源框架,Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可用性的网络服务器和客户端程序。也就是说 Netty 是一个基于 Nio 的编程框架,使用Netty可以快速的开发出一个网络应用。 并且可以在不妥协的情况下实现易于开发、性能、稳定性和灵活性。
.

.

Netty核心概念的介绍

.

1. Bootstrap、ServerBootstrap

介绍:

Bootstrap 的意思是引导,其主要作用是配置整个Netty程序,将各个组件整合起来。ServerBootstrap是服务器端的引导类。 Bootstrap是客户端端的引导类。

  • Bootstrap用于连接远程主机它有一个EventLoopGroup
  • ServerBootstrap用于监听本地端口有两个EventLoopGroup

.

2. EventLoopGroup

介绍:

EventLoopGroup 主要是管理EventLoop的生命周期,可以将其看作是一个线程池,其内部维护了一组EventLoop,每个EventLoop对应处理多个Channel,而一个Channel只能对应一个EventLoop

补充:

其中 EventLoop 维护了一个线程和任务队列,支持异步提交执行任务 。

.

3. Channel(数据传输流通道)

介绍:

WebSocket进行 I/O 操作(例如读取,写入,连接和绑定)的组件的枢纽,Channel表示可以理解为一个连接,可以理解为每一个请求,就是一个Channel

主要实现:

  • FileChannel 文件通道,用于文件的读和写
  • DatagramChannel 用于 UDP 连接的接收和发送
  • SocketChannel 把它理解为 TCP 连接通道,简单理解就是TCP 客户端
  • ServerSocketChannel TCP对应的服务端,用于监听某个端口进来的请求

主要类:

1. ChannelHandler:

介绍:

业务逻辑处理器,用于处理业务请求与响应,分为ChannelInboundHandlerChannelOutboundHandler

1. ChannelInboundHandler:

作用: 处理进站数据和所有状态更改事件(进站指的是读操作等由通道引发的事件)

2. ChannelOutboundHandler:

作用: 处理出站数据,允许拦截各种操作(出站指的是写操作等由用户触发的事件,发送到远方服务器的事件)

2. ChannelPipeline:

介绍:

ChannelPipeline其实就是一个ChannelHandler容器,里面包括一系列的 ChannelHandler 实例,用于拦截流经一个Channel 的入站和出站事件,主要用于保存处理过程需要用到的ChannelHandlerChannelHandlerContext

3. ChannelHandlerContext:

介绍:

允许与其关联的ChannelHandler与它相关联的ChannlePipeline和其它ChannelHandler来进行交互。它可以通知相同ChannelPipeline中的下一个ChannelHandler,也可以对其所属的ChannelPipeline进行动态修改。用于传输业务数据

4. ChannelContext:

介绍:

Channel(通信管道)的上下文

在这里插入图片描述

交互流程:

  1. 事件传递给 ChannelPipeline 的第一个 ChannelHandler
  2. ChannelHandler 通过关联的 ChannelHandlerContext 传递事件给 ChannelPipeline 中的 下一个
  3. ChannelHandler 通过关联的 ChannelHandlerContext 传递事件给 ChannelPipeline 中的 下一个

.

4. Futrue、ChannelFuture

介绍:

Future提供了另一种在操作完成时通知应用程序的方式。可以看作是一个异步操作结果的占位符;它将在未来的某个时刻完成,并提供对其结果的访问。

补充:

Netty的每一个出站操作都会返回一个ChannelFutureFuture上面可以注册一个监听器,当对应的事件发生后会出发该监听器。

.

5. ByteBuf(储字节的容器)

介绍:

ByteBuf是一个存储字节的容器,最大特点就是使用方便,它既有自己的读索引和写索引,方便你对整段字节缓存进行读写,也支持get/set,方便你对其中每一个字节进行读写,他的数据结构如下图所示:

在这里插入图片描述

ByteBuf的模式:

1. Heap Buffer(堆缓冲区)

堆缓冲区是ByteBuf最常用的模式,他将数据存储在堆空间

2. Direct Buffer(直接缓冲区)

直接缓冲区是ByteBuf的另外一种常用模式,他的内存分配都不发生在堆,jdk1.4引入的nioByteBuffer类允许jvm通过本地方法调用分配内存。这样做有两个好处如下:

  • 通过免去中间交换的内存拷贝, 提升IO处理速度; 直接缓冲区的内容可以驻留在垃圾回收扫描的堆区以外

  • DirectBuffer 在 -XX:MaxDirectMemorySize=xxM大小限制下, 使用 Heap 之外的内存, GC对此”无能为力”,也就意味着规避了在高负载下频繁的GC过程对应用线程的中断影响

3. Composite Buffer(复合缓冲区)

复合缓冲区相当于多个不同ByteBuf的视图,这是netty提供的,jdk不提供这样的功能

.

6. Decoder(解码器)

介绍:

负责将消息从字节或其他序列形式转成指定的消息对象;类型有:1. 解码字节到消息。2.解码消息到消息

主要类:

1. ByteToMessageDecoder抽象类

作用: 将字节消息解码成Object对象

主要方法:

1. decode(ChannelHandlerContext, ByteBuf, List<Object>)方法

作用:ByteBuf数据解码成其他形式的数据。

2. decodeLast(ChannelHandlerContext, ByteBuf, List<Object>)方法

实际上调用的是decode(...)

主要流程:
在这里插入图片描述

2. MessageToMessageDecoder抽象类

作用: 将消息对象转成消息对象

主要方法:

1. decode(ChannelHandlerContext, ByteBuf, List<Object>)方法

作用:ByteBuf数据解码成其他形式的数据。

主要流程:
在这里插入图片描述

Netty中常用的自带解码器:

  • DelimiterBasedFrameDecoder: 分隔符解码器,以设定的符号作为消息的结束解决粘包问题
  • FixedLengthFrameDecoder: 定长解码器,作用于定长的消息
  • LineBasedFrameDecoder: 按照每一行进行分割,也就是特殊的分隔符解码器,它的分割符为\n或者\r\n
  • LengthFieldBasedFrameDecoder: 通过消息中设置的长度字段来进行粘包处理。该解码器总共有5个参数
  • int maxFrameLength: 单个包的最大大小
  • int lengthFieldOffset: 定义长度的字段的相对包开始的偏移量
  • int lengthFieldLength: 定义长度字段所占字节数
  • int lengthAdjustment: 数据长度字段之后剩下包的字节数 - 数据长度取值(也就是长度字段之后的所有非数据的其他信息)
  • int initialBytesToStrip: 从包头开始,要忽略的字节数
  • HttpRequestDecoder: 将字节解码为HttpRequestHttpContentLastHttpContent消息
  • HttpResponseDecoder 将字节解码为HttpResponseHttpContentLastHttpContent消息
  • HttpObjectAggregator 将http消息的多个部分聚合起来形成一个FullHttpRequest或者FullHttpResponse消息
    在这里插入图片描述

.

7. Encoder(编码器)

介绍:
将消息对象转成字节或其他序列形式在网络上传输;类型有:1. 消息对象编码成消息对象。2.消息对象编码成字节码

主要类:

1. MessageToByteEncoder抽象类

作用:ByteToMessageDecoder抽象类相反

主要流程:
在这里插入图片描述

2. MessageToMessageEncoder抽象类

作用:MessageToMessageDecoder抽象类相反

主要流程:
在这里插入图片描述

.

.

使用Netty搭建安卓Socket客户端的使用

.

1. 在 build.gradle 添加Netty的依赖

dependencies {
   
	implementation 'io.netty:netty-all:4.1.23.Final'
}

.

2. 使用Netty的简单使用

2.1. 创建ConnectionWatchdog类

	//创建接口
	interface ChannelHandlerHolder {
   

    	fun handlers(): Array<ChannelHandler>
	}

	//创建接口
	interface ReconnectSuccessHolder {
   

    	fun reconnectSuccess(channel: SocketChannel?)
	}

	/**
	 * 连接监控器
	 * */
	@ChannelHandler.Sharable
	abstract class ConnectionWatchdog(
	                                  val bootstrap: Bootstrap,
	                                  val timer: Timer,
	                                  val port: Int,
	                                  val host: String,
	                                  val reconnect: Boolean
	                                  ) : ChannelInboundHandlerAdapter(), TimerTask, ChannelHandlerHolder, ReconnectSuccessHolder {
   
	
	
	    private var attempts: Int = 0
	
		//TimerTask接口的方法
	    override fun run(p0: Timeout?) {
   
	        //bootstrap已经初始化好了,只需要将handler填入就可以了
	        val future: ChannelFuture = synchronized(bootstrap) {
   
	
	            bootstrap.handler(object : ChannelInitializer<Channel>() {
   
	
	                @Throws(Exception::class)
	                override fun initChannel(ch: Channel) {
   
	                    ch.pipeline()
	                      .addLast(*handlers())
	                }
	            })
	            bootstrap.connect(host, port)
	        }
	        //future对象
	        future.addListener {
    f ->
	            val succeed = f.isSuccess
	
	            //如果重连失败,则调用ChannelInactive方法,再次出发重连事件,一直尝试12次,如果失败则不再重连
	            if (!succeed) {
   
	                Log.i("netty", "重连失败")
	                (f as ChannelFuture).channel().pipeline().fireChannelInactive()
	            } else {
   
	                val socketChannel = future.channel() as SocketChannel
	                reconnectSuccess(socketChannel)
	                Log.i("netty", "重连成功")
	            }
	        }
	    }
	
	
	    override fun channelInactive(ctx: ChannelHandlerContext?) {
   
	        super.channelInactive(ctx)
	        Log.i("netty", "链接关闭")
	        if(reconnect){
   
	
	
				Log.i("netty", "链接关闭,将进行重连")
				//重连的间隔时间会越来越长
	            timer.newTimeout(this, 10, TimeUnit.SECONDS)
	        }
	        ctx!!.fireChannelInactive()
	    }
	
	    override fun channelActive(ctx: ChannelHandlerContext?) {
   
	        super.channelActive(ctx)
	        Log.i("netty", "当前链路已经激活了,重连尝试次数重新置为0")
	        attempts = 0
	        ctx!!.fireChannelActive()
	
	    }
	}

.

**2.2. ConnectorIdleStateTrigger**

	/**
	 * 连接空闲处理
	 * */
	
  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android可以使用Netty框架来进行网络通信和数据传输。Netty是一个高性能的网络通信框架,它提供了简单易用的API,可以轻松地构建TCP、UDP、HTTP和WebSocket等不同协议的通信应用。 在Android开发中,使用Netty可以实现高效稳定的数据传输和连接管理。通过Netty的异步事件驱动模型,Android应用程序可以更好地处理网络通信并实现高并发的数据传输。而且Netty使用NIO技术,可以大大提高网络通信的效率和吞吐量,并降低资源的占用率。 在使用Netty时,Android应用可以通过定制Handler实现自定义的网络通信协议,并通过管道(Pipeline)将处理逻辑按照顺序链接起来,并交给事件处理器(EventLoop)来处理。这样可以轻松地实现复杂的网络应用。 总之,使用Netty可以为Android应用程序提供一种快速、高效、稳定的网络通信方案,并极大地提高网络通信的效率和数据传输的性能。 ### 回答2: Android可以使用Netty作为网络编程框架,通过Netty可以快速地实现一个高性能的服务器/客户端应用程序。Netty是一个基于Java NIO实现的网络编程框架,它提供了异步的、事件驱动的网络通讯方式,很好地解决了原生的Java NIO编程难度大、学习曲线陡峭的问题。Netty中的核心组件包括了Channel、EventLoop、ChannelHandler等,这些组件共同协作,构建了Netty的基本网络编程框架。 在Android使用Netty时,我们可以创建一个客户端或服务端应用,连接或监听网络,读写数据等。Netty可以实现多种协议的编解码,例如HTTP、WebSocket、TCP等,非常灵活。此外,Netty还提供了一套高效的线程池机制,可以充分利用CPU资源,提高网络编程的效率。 总的来说,Android使用Netty可以帮助我们更轻松地实现服务器/客户端应用程序,提高网络编程效率和性能。但是,需要注意的是,由于Netty是一个基于Java NIO实现的框架,它的设计思想与传统的I/O编程不同,对于初学者来说难度还是较大,需要花费一定的学习时间。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值