Netty学习一
2021-04-09 05:26
标签:src inf web text date() 存储 outbound erb 入门 Netty概述 Netty是一个是一款异步的事件驱动的网络应用程序框架,何为异步?异步的对立就是同步,同步就好比你有一个秘书,你叫你秘书外出采购Netty学习书籍,你在办公室等你秘书回来,期间什么事情都不能做,一直等到你秘书回来从她手上拿走书本后才可以匆匆忙忙上厕所;而异步就好比你叫你秘书外出采购Netty学习书籍后,你可以去访问Netty官网,参照官网的用户指导做个练习,你秘书回来后会通知你买到书籍与否。 Netty的用处 首先Netty是一个网络应用框架,可以基于Netty开发一个基于http/https协议的服务器,这样你可以用浏览器访问你的服务;也可以基于它开发一个websocket协议的应用服务,这样可以实现前端与后台长连接全双工的交互;还可以基于它实现rpc应用等等。 Netty主要组件 简单描述一下Netty主要组件,在后面会详细讨论。 ChannelHandler: 通道处理器,可以处理客户端和服务端之间传递的数据,在开发中一般用来做编解码处理和系统业务转发处理。 ChannelHandler有两大常用子接口:一个是处理入栈数据的接口ChannelInboundHandler,另一个是处理出栈数据的接口ChannelOutboundHandler。 出栈入栈:对服务端而言,入栈就是数据从客户端--->服务端的行为,出栈就是服务端--->客户端的行为;对于客户端而言,入栈就是服务端--->客户端的行为,出栈就是客户端--->服务端的行为(--->描述数据流动)。 ChannelPipeline: ChannelPipeline可以简单看作一个ChannelHandler的双向链表(链表中实际上存储的是ChannelHandlerContext),在ChannelPipeline中调用addLast()方法可以将ChannelHandler添加到链表末端(实际末端还有一个tail节点,开发过程中不用管),ChannelPipeline运行过程中的调用链如下图所示: EventLoop: 事件循环器,可以看作是一个死循环线程,每次循环都会检测注册到自己的channel,若有事件(连接激活事件、通道可读事件、通道关闭事件等)发生会调用ChannelPipeline中第一个ChannelHandlerContext EventLoopGroup: 事件循环组,可以简单看作EventLoop的容器,默认会根据cpu核数乘以2来创建EventLoop BootStrap: 引导器,用于配置Netty程序相关内容以及启动Netty应用,其中group()方法用于添加EventLoopGroup,channel()方法用于指定channel的实现类handler()方法用接收一个ChannelInitializer对象,该对象重写的initChannel(SocketChannel socketChannel)方法,在该方法中调用socketChannel.pipeline().addLast()可以将处理器添加到ChannelPipeline中。 数据缓冲池,该缓冲区的特点是既可以读也可以写,ByteBuf有三个关键指针readerIndex、 writerIndex 和 capacity,当数据写入ByteBuf时writeIndex会向后移动数据字的节数个位置(写入一个字节writeIndex向后移动一位),writeIndex最大不能超过capacity,当从ByteBuf读取数据时readerIndex会向后移动数据的字节数个位置(写入一个字节readIndex向后移动一位)。三个指针将ByteBuff划分成三个区,如下图所示: Netty的hello world 参考github上Netty的官方例子并简化后得到以下的Netty快速入门例子,为了方便排版,改造成两个文件,一个服务端和一个客户端。 服务器端代码HelloWorldServer.java 客户端代码HelloWorldClient.java 代码说明 全部代码在https://github.com/yuchongshen/netty_example/tree/master/src/org/shenyuchong/simple_helloworld Netty学习一 标签:src inf web text date() 存储 outbound erb 入门 原文地址:https://www.cnblogs.com/shenyuchong/p/12449861.html I/O 请求
|
+---------------------------------------------------+---------------+
| ChannelPipeline | |
| \|/ |
| +---------------------+ +-----------+----------+ |
| | 入栈处理器 n | | 出栈处理器 1 | |
| +----------+----------+ +-----------+----------+ |
| /|\ | |
| | \|/ |
| +----------+----------+ +-----------+----------+ |
| | 入栈处理器 n-1 | | 出栈处理器 2 | |
| +----------+----------+ +-----------+----------+ |
| /|\ | |
| | | |
| | \|/ |
| +----------+----------+ +-----------+----------+ |
| | 入栈处理器 2 | | 出栈处理器 m-1 | |
| +----------+----------+ +-----------+----------+ |
| /|\ | |
| | \|/ |
| +----------+----------+ +-----------+----------+ |
| | 入栈处理器 1 | | 出栈处理器 m | |
| +----------+----------+ +-----------+----------+ |
| /|\ | |
+---------------+-----------------------------------+---------------+
| \|/
+---------------+-----------------------------------+---------------+
| | | |
| [ 通道读 ] [ 通道写 ] |
+-------------------------------------------------------------------+
ByteBuf:
+-------------------+------------------+------------------+
| 丢弃区域 | 可读区域 | 可写区域 |
+-------------------+------------------+------------------+
| | | |
0
package org.shenyuchong.simple_helloworld;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
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 java.util.Date;
public class HelloWorldServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer
package org.shenyuchong.simple_helloworld;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.util.Random;
public class HelloWorldClient {
public static void main(String[] args) throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer