netty5入门教程
1、Netty是什么?
本质:JBoss做的一个Jar包
目的:快速开发高性能、高可靠性的网络服务器和客户端程序
优点:提供异步的、事件驱动的网络应用程序框架和工具
通俗的说:一个好使的处理Socket的东东
2、Netty的异步事件驱动模型主要涉及到下面几个核心的概念
Channel:表示一个与socket关联的通道
ChannelPipeline: 管道,一个Channel拥有一个ChannelPipeline,ChannelPipeline维护着一个处理链(严格的说是两 个:upstream、downstream),处理链是由很 多通道处理器ChannelHandler所构成,每个ChannelHandler处理完以 后会传递给链中的下一个通道处理器继续处理。
ChannelHandler:通道处理器,用户可以定义自己的处理句柄来处理每个请求,或发出请求前进行预处理,典型的有编码/解码器:decoder、encoder。
ChannelEvent:事件,是整个模型的处理对象,当产生或触发(fire)一个事件时,该事件会沿着ChannelPipeline处理链依次被处理。 ChannelFuture: 异步结果,这个是异步事件处理的关键,当一个事件被处理时,可以直接以ChannelFuture的形式直接返回,不用在当前操作中被阻塞。可以通过 ChannelFuture得到最终的执行结果,具体的做法是在ChannelFuture添加监听器listener,当操作最终被执行完 后,listener会被触发,我们可以在listener的回调函数中预定义我们的业务代码。

ChannelPipeline实际上维持了两个处理链:upstream、downstream。 Upstream一般处理来自Channel的读事件,而downstream一般处理向Channel的写事件。需要注意的是,这两个处理链是相互独立 的,在upstream链中传递到最后一个ChannelHandler处理后,不会再传递到downstream链中继续处理。
在downstream链的末端会有个ChannelSink处理,用户可以自定义这个ChannelSink的实现,系统也有个默认的实现,当downstream链中最后一个ChannelHandler处理完后会被传递给这个ChannelSink进行最后的处理。
3、Demo
3.1、NettyServer.java
package com.jacky.server; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler; public class NettyServer { private static Logger logger = Logger.getLogger(NettyServer.class);
private int port;
public NettyServer(int port) {
this.port = port;
bind();
} private void bind() { EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(boss, worker);
bootstrap.channel(NioServerSocketChannel.class);
bootstrap.option(ChannelOption.SO_BACKLOG, 1024); //连接数
bootstrap.option(ChannelOption.TCP_NODELAY, true); //不延迟,消息立即发送
bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); //长连接
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel)
throws Exception {
ChannelPipeline p = socketChannel.pipeline();
p.addLast(new NettyServerHandler());
}
});
ChannelFuture f = bootstrap.bind(port).sync();
if (f.isSuccess()) {
logger.debug("启动Netty服务成功,端口号:" + this.port);
}
// 关闭连接
f.channel().closeFuture().sync(); } catch (Exception e) {
logger.error("启动Netty服务异常,异常信息:" + e.getMessage());
e.printStackTrace();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
} public static void main(String[] args) throws InterruptedException { NettyServer server= new NettyServer(9999); } }
3.2、NettyServerHandler.java
package com.jacky.server; import java.io.UnsupportedEncodingException;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext; public class NettyServerHandler extends ChannelHandlerAdapter { @Override
public void channelRead(ChannelHandlerContext context, Object msg) {
ByteBuf buf = (ByteBuf) msg;
String recieved = getMessage(buf);
System.out.println("服务器接收到消息:" + recieved);
try {
context.writeAndFlush(getSendByteBuf("APPLE"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} /*
* 从ByteBuf中获取信息 使用UTF-8编码返回
*/
private String getMessage(ByteBuf buf) { byte[] con = new byte[buf.readableBytes()];
buf.readBytes(con);
try {
return new String(con, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
} private ByteBuf getSendByteBuf(String message)
throws UnsupportedEncodingException { byte[] req = message.getBytes("UTF-8");
ByteBuf pingMessage = Unpooled.buffer();
pingMessage.writeBytes(req); return pingMessage;
}
}
3.3、NettyClient.java
package com.jacky.client; import java.util.concurrent.TimeUnit; import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler; public class NettyClient { /*
* 服务器端口号
*/
private int port; /*
* 服务器IP
*/
private String host; public NettyClient(int port, String host)
throws InterruptedException {
this.port = port;
this.host = host;
start();
} private void start() throws InterruptedException { EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap();
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
bootstrap.group(eventLoopGroup);
bootstrap.remoteAddress(host, port);
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel)
throws Exception {
socketChannel.pipeline().addLast(new NettyClientHandler());
}
});
ChannelFuture future = bootstrap.connect(host, port).sync();
if (future.isSuccess()) {
SocketChannel socketChannel = (SocketChannel) future.channel();
System.out.println("----------------connect server success----------------");
}
future.channel().closeFuture().sync();
} finally {
eventLoopGroup.shutdownGracefully();
}
} public static void main(String[] args) throws InterruptedException { NettyClient client = new NettyClient(9999, "localhost"); }
}
3.4、NettyClientHandler.java
package com.jacky.client; import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
public class NettyClientHandler extends ChannelHandlerAdapter {
private ByteBuf firstMessage;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
byte[] data = "服务器,给我一个APPLE".getBytes();
firstMessage=Unpooled.buffer();
firstMessage.writeBytes(data);
ctx.writeAndFlush(firstMessage);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
ByteBuf buf = (ByteBuf) msg;
String rev = getMessage(buf);
System.out.println("客户端收到服务器数据:" + rev);
}
private String getMessage(ByteBuf buf) {
byte[] con = new byte[buf.readableBytes()];
buf.readBytes(con);
try {
return new String(con, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
netty5入门教程的更多相关文章
- wepack+sass+vue 入门教程(三)
十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...
- wepack+sass+vue 入门教程(二)
六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...
- wepack+sass+vue 入门教程(一)
一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...
- Content Security Policy 入门教程
阮一峰文章:Content Security Policy 入门教程
- gulp详细入门教程
本文链接:http://www.ydcss.com/archives/18 gulp详细入门教程 简介: gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优 ...
- UE4新手引导入门教程
请大家去这个地址下载:file:///D:/UE4%20Doc/虚幻4新手引导入门教程.pdf
- ABP(现代ASP.NET样板开发框架)系列之2、ABP入门教程
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之2.ABP入门教程 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...
- webpack入门教程之初识loader(二)
上一节我们学习了webpack的安装和编译,这一节我们来一起学习webpack的加载器和配置文件. 要想让网页看起来绚丽多彩,那么css就是必不可少的一份子.如果想要在应用中增加一个css文件,那么w ...
- 转载:TypeScript 简介与《TypeScript 中文入门教程》
简介 TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.安德斯·海尔斯伯格,C#的首席架构 ...
随机推荐
- linux shutdown命令
shutdown [-t 秒] [-arkhncfF] 时间 [警告信息] 常用选项与参数: -t sec : -t 后面加秒数,亦即『过几秒后关机』的意思 -k : 不要真的关机,只是发送警告信息出 ...
- HDUOJ------敌兵布阵
敌兵布阵 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submissi ...
- www.pythonchanlleges.com
0. 2**38 1. 字符串映射 s = """ g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ...
- POJ 3007 Organize Your Train part II (字典树 静态)
Organize Your Train part II Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6478 Acce ...
- js LINQ教程
在说LINQ之前必须先说说几个重要的C#语言特性 一:与LINQ有关的语言特性 1.隐式类型 (1)源起 在隐式类型出现之前, 我们在声明一个变量的时候, 总是要为一个变量指定他的类型 甚至在fore ...
- Linux内核“问题门” - 学习问题、经验集锦
陈宪章说:“学贵有疑,小疑则小进,大疑则大进.疑者,觉悟之机也,一番觉悟一番长进.” 培根说:“多问的人将多得.” 还在学校的时候导师在激情讲演之后对着会议室里形态各异但均静默不语的我们痛心疾首的说: ...
- iOS 关于 设计模式 与网友讨论实录
关于 设计模式 与网友讨论实录 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留 ...
- C#--类之隐藏基类的成员
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- MVC 之Action
下面我要重新温习一下,MVC控制器中的Action方法相关概念: 1.Action方法必须是public,不能是private或者是protected; 2.Action方法不能够被重载: 3.Act ...
- [转]Microsoft Office 2010、Visio 2010、Project 2010官方中文版+有效激活方法
本文刊发的Office 2010.Project 2010O.Visio 2010:(1)均为“微软批量授权中心”原版光盘镜像:(2)均提供了32位(x86)和64位(x64)两种版本.为使大家了解各 ...