Netty:初识Netty
前文总结了NIO的内容,有了NIO的一些基础之后,我们就可以来看下Netty。Netty是Java领域的高性能网络传输框架,RPC的技术核心就是网络传输和序列化,所以Netty给予了RPC在网络传输领域巨大的支持。
一个简单的Netty代码实现
网络传输基于的是TCP协议,所以会有服务端和客户端之分,而Netty是网络传输框架,所以一个完整的Netty代码至少是有服务端和客户端的。本文代码基于Netty4.1.15。
服务端:
public class DemoServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup).
channel(NioServerSocketChannel.class).
childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
ch.pipeline().addLast(new DemoServerHandler());
}
});
ChannelFuture future = serverBootstrap.bind(8899).sync();
future.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
public class DemoServerHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("" + ctx.channel().remoteAddress() + "," + msg);
ctx.channel().writeAndFlush("from server" + UUID.randomUUID());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
客户端:
public class DemoClient {
public static void main(String[] args) throws Exception{
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
try{
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
ch.pipeline().addLast(new DemoClientHandler());
}
});
ChannelFuture channelFuture = bootstrap.connect("localhost",8899).sync();
channelFuture.channel().closeFuture().sync();
}finally {
eventLoopGroup.shutdownGracefully();
}
}
}
public class DemoClientHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("" + ctx.channel().remoteAddress());
System.out.println("client output:" + msg);
ctx.writeAndFlush("from client" + LocalDateTime.now());
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
String msg = "来自客户端的问候!";
ctx.writeAndFlush(msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
来看下这个简单的代码做了什么:
1、服务端启动后,客户端先向服务端发起连接建立;
2、连接建立后,触发客户端的channelActive方法,该方法向服务端发出了一条信息,这条信息默认在网络中是会转成字节的形式来传输的,因为TCP的数据传输都是基于字节的,这个过程也叫做编码;
3、服务端收到信息后,会被服务端的Handler,其实就是StringDecoder先做处理,从字节变成了字符,这个过程也叫做解码;
4、此时对于DemoServerHandler来说,信息已经变成了符合自己的String类型,所以channelRead0方法会被调用,输出信息,同时向客户端发出信息,信息又会转成字节的信息传向客户端;
5、客户端收到信息后,会被客户端解码成字符,触发客户端的channelRead0方法,输出客户端地址和收到的信息,再向服务端发送时间戳;
6、循环往复上述3-5,死循环;
模块化
从上述这个简单的DEMO中,我们可以提取出Netty的核心模块:
1、Channel、EventLoop、ChannelFuture
Channel接口:基本的IO操作(bind()/connect()/read()/write())依赖于底层网络传输所提供的原语。在我们这个DEMO中,能看到NioServerSocketChannel和NioSocketChannel,NioServerSocketChannel使用基于NIO选择器的实现来接受新连接,NioSocketChannel使用基于NIO选择器的实现来建立和处理新连接。
EventLoop接口:EventLoop定义了Netty的核心抽象,用于处理连接的生命周期中所发生的事件。EventLoop是协调设计的一部分,采用了两个基本的API:并发和网络编程。在我们这个DEMO中,能看到NioEventLoop,NioEventLoop就是一个Reactor,是整个Netty的一个核心。
ChannelFuture接口:Netty中的所有的IO操作都是异步的,因为一个操作可能不会立即返回,所以我们需要一种用于在之后某个时间点确定其结果的方法。为此,Netty提供了ChannelFuture接口,其addListener()方法注册了一个ChannelFutureListener,以便在某个操作完成是得到通知。
2、ChannelHandler、ChannelPipeline
ChannelHandler接口:从应用程序开发人员的角度来看,ChannelHandler是Netty的主要组件,它充当了所有处理入站和出站数据的应用程序逻辑的容器,因为ChannelHandler的方法是由事件来触发的。在我们这个DEMO中,DemoClientHandler、DemoServerHandler就是两个自定义的ChannelHandler,DemoClientHandler在连接一建立的时候,就触发了channelActive方法,然后DemoServerHandler在channelRead0方法中读取了其传输的信息。
ChannelPipeline接口:ChannelPipeline为ChannelHandler链提供了容器,并定义了用于该链上传播入站和出站事件流的API。当Channel被创建时,它会被自动的分配到它所专属的ChannelPipeline。在我们的DEMO中,一个ChannelInitializer的实例被注册到ServerBootStrap或者BootStrap,当它的initChannel方法被调用的时候,ChannelInitializer将在ChannelPipeline中安装一组自定义的ChannelHandler,最后ChannelInitializer将它自己从ChannelPipeline中移除。
3、ByteBuf
网络数据的基本单位是字节,NIO提供了ByteBuffer作为网络数据的字节容器,但是ByteBuffer本身设计并不优雅,使用繁琐,Netty使用ByteBuf来替代ByteBuffer,在我们的DEMO中,不能直接看到ByteBuf,但是在Netty提供的内置编解码器StringDecoder/StringEncoder中,操作的对象就是ByteBuf。
4、ServerBootStrap、BootStrap
ServerBootStrap和BootStrap是一个非常抽象的概念。ServerBootStrap是Netty创建服务器的辅助类,负责封装服务启动的一系列操作。和ServerBootStrap一样,Bootstrap也是封装客户端向服务端发送请求的一系列操作。
5、Codec
通过Netty发送和接收一个消息的时候,就会发生一次数据转换,入站消息会被解码,也就是从字节转换为原本的形式,如果是出站消息,就会从一种形式变成字节,这个就是编码,编解码的根本原因就是因为网络数据就是一系列的字节。在我们的DEMO中,StringEncoder和StringDecoder就是编解码器。
最后总结一下:
1、通过一个简单的DEMO,介绍了一下Netty,站在应用的角度看了下Netty是如何运行的;
2、从DEMO中提取出Netty的重要的模块,简单介绍一下各个模块,在后续的文章中将详细介绍每个模块组件。
参考资料:
https://netty.io/wiki/user-guide-for-4.x.html
Netty:初识Netty的更多相关文章
- DotNetty网络通信框架学习之初识Netty
p{ text-align:center; } blockquote > p > span{ text-align:center; font-size: 18px; color: #ff0 ...
- Netty1:初识Netty
为什么使用Netty Netty是业界最流行的NIO框架之一,它的健壮性.功能.性能.可定制性.可扩展性在同类框架中都是首屈一指的,它已经得到了成百上千的商用项目的证明.对于为什么使用Netty这个话 ...
- Netty(一):初识Netty
Netty是什么? Netty是由JBOSS提供的一个java开源框架. Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序. 封装了JDK底 ...
- 【Netty】Netty入门之WebSocket小例子
服务端: 引入Netty依赖 <!-- netty --> <dependency> <groupId>io.netty</groupId> <a ...
- Netty学习——Netty和Protobuf的整合(二)
Netty学习——Netty和Protobuf的整合(二) 这程序是有瑕疵的,解码器那里不通用,耦合性太强,有两个很明显的问题,但是要怎么解决呢?如:再加一个内部类型 Person2,之前的代码就不能 ...
- Netty学习——Netty和Protobuf的整合(一)
Netty学习——Netty和Protobuf的整合 Protobuf作为序列化的工具,将序列化后的数据,通过Netty来进行在网络上的传输 1.将proto文件里的java包的位置修改一下,然后再执 ...
- [Netty 1] 初识Netty
1. 简介 最早接触netty是在阅读Zookeeper源码的时候,后来看到Storm的消息传输层也由ZMQ转为Netty,所以决心好好来研究和学习一下netty这个框架. Netty项目地址:htt ...
- Netty 学习 一、初识Netty【原创】
在过去几年的工作和学习中,比较关注高层次的应用开发,对底层探究较少.实现Web应用的开发,主要依赖Tomcat.Apache等应用服务器,程序员无需了解底层协议,但同样限制了应用的性能和效率.现在开始 ...
- 初识Netty
我们已经了解了Socket通信/IO/NIO/AIO编程,对于通信模型已经有了一个初步的认识,其实我们之前所学习的仅仅是一个模型,如果想把这些真正的用于实际工作中去,其实我们之前所学习的仅仅是一个模型 ...
随机推荐
- 【h5ai】搭建服务器目录
在前几天,我帮人安装h5ai这个东西,结果直接踩坑,装了一个下午,打算自己也装一个,顺便写一下教程 最终效果演示: https://larsjung.de/h5ai/demo/ 服务器 服务器这里推荐 ...
- Vue源码之组件化/生命周期(个人向)
大致流程 具体流程 组件化 (createComponent) 构造⼦类构造函数 const baseCtor = context.$options._base // plain options ob ...
- 基于python openOPC的监控页面一
笔者涉猎的工业领域项目遇到一个需求,需要把底层设备(表记)的状态和运行数据集中放到一个监控画面进行展示,数据需要在界面端实时进行刷新,类似网友的例子,如下图(侵删) 数据需要实时主动刷新,笔者基于多年 ...
- 零基础JavaScript编码(一)
任务目的 JavaScript初体验 初步明白JavaScript的简单基本语法,如变量.函数 初步了解JavaScript的事件是什么 初步了解JavaScript中的DOM是什么 任务描述 参考以 ...
- Vue项目一、node.js和npm的安装和环境搭建
一.为什么安装node.js及npm npm npm是Node.js的包管理工具(package manager),是全球最大的生态系统,同过npm可以找到很多丰富的插件来满足项目的需求. a1.现在 ...
- 基于@vue/cli 的构建项目(3.0)
1.检测node的版本号 注意:1.Vue CLI需要Node.js的版本 8.9+(推荐8.11.0+) 所以在安装Vue CLI之前先看下node的版本 node -v 2.安装@vue/cli ...
- XCTF---easyjni的WriteUp
一.题目来源 题目来源:XCTF的mobile区的easyjni题目. 题目下载地址:题目链接地址 二.解题过程 1.下载好题目后,安装到夜神模拟器中,发现有一个输入框和一个按 ...
- 17-Java-文件上传报错(commons-fileupload包和commons-io包不支持JDK版本:UnsupportedClassVersionError: org/apache/commons/io/IOUtils : Unsupported major.minor version 52.0)
文件上传报错(commons-fileupload包和commons-io包不支持JDK版本) 这个bug可把我弄惨了!!!我代码是想通过写个文件上传,我写的文件上传需要用到commons-fileu ...
- SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1-Spr ...
- nsq 初学使用日记
win下更加直观一些,所以不使用liunx 第一步下载 nsq 下载地址 https://github.com/nsqio/nsq.git 使用git clone或者go get 下载下来 第二部 编 ...