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 urrent.TimeUnit;
import org.apache.log4j.Logger;
import ioty.bootstrap.ServerBootstrap;
import ioty.channel.ChannelFuture;
import ioty.channel.ChannelInitializer;
import ioty.channel.ChannelOption;
import ioty.channel.ChannelPipeline;
import ioty.channel.EventLoopGroup;
import ioty.channel.nio.NioEventLoopGroup;
import ioty.channel.socket.SocketChannel;
import ioty.channel.socket.nio.NioServerSocketChannel;
import dec.LengthFieldBasedFrameDecoder;
import ioty.handler.timeout.IdleStateHandler;
public class NettyServer {
private static Logger logger = Logger(NettyServer.class);
bootstrap 5private 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.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) {
<("启动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 ioty.buffer.ByteBuf;
import ioty.buffer.Unpooled;
import ioty.channel.ChannelHandlerAdapter;
import ioty.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 adableBytes()];
try {
return new String(con, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
private ByteBuf getSendByteBuf(String message)
throws UnsupportedEncodingException {
byte[] req = Bytes("UTF-8");
ByteBuf pingMessage = Unpooled.buffer();
pingMessage.writeBytes(req);
return pingMessage;
}
}
3.3、NettyClient.java
package com.jacky.client;
import urrent.TimeUnit;
import ioty.bootstrap.Bootstrap;
import ioty.channel.ChannelFuture;
import ioty.channel.ChannelInitializer;
import ioty.channel.ChannelOption;
import ioty.channel.EventLoopGroup;
import ioty.channel.nio.NioEventLoopGroup;
import ioty.channel.socket.SocketChannel;
import ioty.channel.socket.nio.NioSocketChannel;
import dec.LengthFieldBasedFrameDecoder;
import ioty.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.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel)
throws Exception {
socketChannel.pipeline().addLast(new NettyClientHandler());
}
});
ChannelFuture future = t(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;
SimpleDateFormat;
import java.util.Date;
import urrent.TimeUnit;
import ioty.buffer.ByteBuf;
import ioty.buffer.Unpooled;
import ioty.channel.ChannelHandlerAdapter;
import ioty.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 adableBytes()];
try {
return new String(con, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论