Netty 入门案例源码+注释
1.创建maven项目,引入Netty 依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
2.项目结构
3.编写HelloNettyServer
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class HelloNettyServer {
public static void main(String[] args) throws InterruptedException {
//创建一对线程组,
//定义主线程,用于接受客户端的连接,但是不会做任何处理,跟老板一样,不做事。
EventLoopGroup bossGroup = new NioEventLoopGroup();
//定义从线程,老板线程组会把任务给它,让手下去做。
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
//netty服务器的创建
//ServerBootstrap是一个启动类
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup) //设置主从线程类
.channel(NioServerSocketChannel.class) //设置nio的双向通道
.childHandler(new HelloServerInitializer()); //子处理器,用于处理workerGroup
//启动server,设置8088 为启动的端口号,同时启动方式为同步
ChannelFuture channelFuture = serverBootstrap.bind(8088).sync();
//监听关闭的channel,设置为同步方式
channelFuture.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
4.编写HelloServerInitializer
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpServerCodec;
/*
* 这是一个初始化器,当channel注册后,W
* 会执行里面的相应的初始化方法。
* */
public class HelloServerInitializer extends ChannelInitializer {
@Override
protected void initChannel(Channel channel) throws Exception {
//通过SocketChannel 去获取相应的管道
ChannelPipeline pipeline = channel.pipeline();
// 通过管道添加handler
//httpServerCodec 是由netty自己提供助手类,可以理解为拦截器
//当请求到服务器,我们需要解码,相应到客户端做编码
pipeline.addLast("HttpServerCodec",new HttpServerCodec());
//添加自定义的助手类,返回hello,netty
pipeline.addLast("customHandler",new CustomHandler());
}
}
5.编写CustomHandler
/*
* 创建自动一助手类
* */
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
//SimpleChannelInboundHandler:对于请求来说,其实相当于[入栈,入境]
public class CustomHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
//获取Channel
Channel channel = ctx.channel();
if (msg instanceof HttpRequest){
//显示客户端的远程地址
System.out.println(channel.remoteAddress());
//定义发送的数据消息
ByteBuf content = Unpooled.copiedBuffer("hello netty", CharsetUtil.UTF_8);
//构建一个http response
FullHttpResponse response =
new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK,content);
//为相应增加数据类型和长度
response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes());
//把相应到刷到相应的客户端
ctx.writeAndFlush(response);
}
}
}
6.测试
成功!