目录
项目结构
1.导入netty坐标(pom)
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.48.Final</version>
</dependency>
2.编写入口程序(HelloServers)
package netty;
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 HelloServers {
public static void main(String[] args) throws Exception {
/*定义一对组从线程组*/
/*主线程组,只接收客户端的连接,不做事*/
EventLoopGroup bossEvent = new NioEventLoopGroup();
/*从线程组,从组线程组获取任务,来做任务*/
EventLoopGroup workEvent = new NioEventLoopGroup();
try {
/*新建一个服务器启动*/
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossEvent, workEvent)/*设置主从线程组*/
.channel(NioServerSocketChannel.class) /*设置NIO的双向通道*/
.childHandler(new HelloServerInit()); /*设置子处理器*/
/*启动server,并且设置端口号,为同步启动*/
ChannelFuture channelfuture = serverBootstrap.bind(8088).sync();
/*监听关闭的channel,设置为同步方式*/
channelfuture.channel().closeFuture().sync();
} finally {
/*以优雅的方式关闭*/
bossEvent.shutdownGracefully();
workEvent.shutdownGracefully();
}
}
}
3.编写子处理器(HelloServerInit)
package netty;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;
/** * 初始化器,channel注册后会执行下面的初始化方法 */
public class HelloServerInit extends ChannelInitializer<SocketChannel> {
protected void initChannel(SocketChannel socketChannel) throws Exception {
/*获取对应的管道*/
ChannelPipeline pipeline = socketChannel.pipeline();
/*通过管道添加handler*/
/*HttpServerCodec是netty提供的助手类,类似拦截器(编码/解码)*/
pipeline.addLast("httpServerCodec", new HttpServerCodec());
/*添加自定义助手类*/
pipeline.addLast("customHandler",new CustomHandler());
}
}
4.编写自定义助手类(CustomHandler)
package netty;
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> {
/*从缓冲区读数据*/
protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject)
throws Exception {
/*获取channel*/
Channel channel = channelHandlerContext.channel();
/*筛选请求*/
if (httpObject instanceof HttpRequest) {
/*打印客户端地址*/
System.out.println(channel.remoteAddress());
/*定义发送的消息以及编码方式*/
ByteBuf content = Unpooled.copiedBuffer("hello netty", CharsetUtil.UTF_8);
/*新建一个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());
/*把消息刷到客户端*/
channelHandlerContext.writeAndFlush(response);
}
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("Channel注册");
super.channelRegistered(ctx);
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("Channel解注册");
super.channelUnregistered(ctx);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("Channel活动");
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("Channel不活动");
super.channelInactive(ctx);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
System.out.println("Channel读取完毕");
super.channelReadComplete(ctx);
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
System.out.println("用户事件触发");
super.userEventTriggered(ctx, evt);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
System.out.println("Channel可写更改");
super.channelWritabilityChanged(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("捕获到异常");
super.exceptionCaught(ctx, cause);
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
System.out.println("助手类添加");
super.handlerAdded(ctx);
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
System.out.println("助手类移除");
super.handlerRemoved(ctx);
}
}
5.效果
B/S交互
、
关闭浏览器时
postman
关闭postman时