实现客户端发送请求到服务器,服务端返回一个hello netty
public class HelloServer {
public static void main(String[] args) throws Exception{
//1.定义一对线程组(两队线程池)
EventLoopGroup bossGroup = new NioEventLoopGroup();//主线程组,用于接收客户端的连接,但不做任何处理,跟老板一样,不做事
EventLoopGroup workerGroup = new NioEventLoopGroup();//从线程组,老板线程组会把任务丢给他,让从线程组做任务
try{
//2.netty服务器的创建,serverBootStrap 是一个启动类
ServerBootstrap serverBootstrap =new ServerBootstrap();
//group参数1 主线程组 参数2 从线程组
serverBootstrap.group(bossGroup,workerGroup)//设置主从线程组
.channel(NioServerSocketChannel.class)//channel:当客户端和服务端连接之后,会有相应的双向通道产生,这里定义通道的类型:NioServerSocketChannel 通过class获得
.childHandler(new HelloServerInitializer());//子处理器,用于处理workgroup
//启动server,并且设置8088为启动端口号,同时启动方式为同步
ChannelFuture channelFuture = serverBootstrap.bind(8088).sync();
//监听关闭的channel,设置为同步方式
channelFuture.channel().closeFuture().sync();//以同步的方式监听channel关闭的行为
}finally {
//
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel out.");
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 channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
super.channelRead(ctx, msg);
}
@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 boolean isSharable() {
return super.isSharable();
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
System.out.println("助手类移除");
super.handlerRemoved(ctx);
}
protected void initChannel(SocketChannel socketChannel) throws Exception {
//通过socketchannel获取对应的管道(pipeline)
ChannelPipeline pipeline = socketChannel.pipeline();
//通过管道,添加handler
//HttpServerCodec是netty提供的助手类,可以理解为拦截器
//当请求到服务端,我们需要做解码,响应到客户端做编码
pipeline.addLast("HttpServerCodec",new HttpServerCodec());
//添加自定义助手类,返回“hello netty”
pipeline.addLast("customHandler",new CustomHandler());
}
}
//SimpleChannelInboundHandler<HttpObject> :对于请求来讲,相当于【入站,入境】
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);
//构建一个 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());//设置数据长度
//把响应刷到客户端
channelHandlerContext.writeAndFlush(response);
}
}
}