先来看一下我们需要的流程
1.构建一对主从线程组
2.定义服务器启动类
3.为服务器设置Channel
4.设置处理从线程池的助手类初始化器
5.监听启动和关闭服务器跳
启动器
/*
* 实现 客户端发送一个请求 服务器会返回helloworld
* */
public class HelloServer {
public static void main(String[] args) throws InterruptedException {
//定义一对线程组
//主线程组 用于接收客户端的连接但是不做任何处理
EventLoopGroup bossGroup = new NioEventLoopGroup();
//从线程组 老板线程组会把任务交给从线程组 让其工作
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
//定义服务器ServerBootstrap启动类 服务器的创建
//设置channel
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)//设置组从线程
.channel(NioServerSocketChannel.class)//设置nio的双向通道
.childHandler(new HelloServerInitializer()); //子处理器 用于处理workgroup
//启动server 绑定8088端口号 启动方式为同步
ChannelFuture channelFuture = serverBootstrap.bind(8088).sync();
//监听关闭的channel 设置为同步方式
channelFuture.channel().closeFuture().sync();
} finally {
//关闭主从线程
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
初始化器
```java
/*
* 这是一个初始化器 channel注册 会执行里面相对应的初始化方法
* */
public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {
protected void initChannel(SocketChannel socketChannel) throws Exception {
//通过channel获取pipline
ChannelPipeline pipeline = socketChannel.pipeline();
//pipline如上面图所示 handler我们可以添加进去
//我们需求是在打开网站的时候 返回字符串 这就需要http编解码 器
//后面是netty提供的助手类 可以理解为拦截器
//当请求到我们这 我们需要做解码 响应客户端做编码
pipeline.addLast("httpServerCodec",new HttpServerCodec());
//我们想返回我们字符串 就需要我们自定义我们的助手类
pipeline.addLast("customerHandler",null);
}
}
创建助手类(可以理解为拦截器(不准确))
//对于请求来讲 其实相当于入站 入境
public class CustomerHandler extends SimpleChannelInboundHandler<HttpObject> {
protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject) throws Exception {
//获取channel
Channel channel = channelHandlerContext.channel();
System.out.println(channel.remoteAddress());
//发送内容信息 通过缓存区
ByteBuf content = Unpooled.copiedBuffer("hellonetty", CharsetUtil.UTF_8);
FullHttpResponse defaultHttpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
//为响应在呢个价一个数据类型 和一个长度
defaultHttpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
defaultHttpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
//吧响应刷到客户端
channelHandlerContext.writeAndFlush(defaultHttpResponse);
}
}
助手类的生命周期
@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("channeld读取完毕。。。");
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);
}
利用crul访问 控制台打印