netty 简单的和浏览器交互实现信息回答
强烈推荐去弄懂Netty流程,再来写这个代码:

/** * 实现客户端发送一个请求,服务器返回信息 * [主从线程模型] */ public class HelloServer { public static void main(String[] args) throws InterruptedException { // 主线程组 [接受客户端连接,但不做处理,和老板一样] 这个是主从模式的 EventLoopGroup bosGroup = new NioEventLoopGroup(); //从线程组 【老板线程组把任务丢给他,让手下去做任务 中介....】 EventLoopGroup workerGroup = new NioEventLoopGroup(); try { // netty服务器的创建, ServerBootstrap 是一个启动类 ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bosGroup, workerGroup) // 设置主从线程组 .channel(NioServerSocketChannel.class) // 设置nio的双向通道 .childHandler(new HelloServerInitializer()); // 子处理器,用于处理workerGroup // 启动server,并且设置8088为启动的端口号,同时启动方式为同步 ChannelFuture channelFuture = serverBootstrap.bind(8088).sync(); // 监听关闭的channel,设置为同步方式 channelFuture.channel().closeFuture().sync(); } finally { bosGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }

/** * 初始化器 channel注册后 会执行里面相对应的初始化方法 */ public class HelloServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { //通过SocketChannel去获得对应的管道 ChannelPipeline pipeline = socketChannel.pipeline(); // 当请求到服务端,我们需要做解码,响应到客户端做编码 pipeline.addLast("HttpServerCodec",new HttpServerCodec()); // 添加自定义的助手类,返回 "hello netty" pipeline.addLast("customHandler",new CustomHandler()); } }

/** * @Description: 创建自定义助手类 */ //SimpleChannelInboundHandler: 对于请求来讲,其实相当于[入站,入境] public class CustomHandler extends SimpleChannelInboundHandler<HttpObject> { @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject) throws Exception { // 通过上下文对象获取channel Channel channel = channelHandlerContext.channel(); //判断请求是否Request请求 if (httpObject instanceof HttpRequest){ // 显示客户端的远程地址 System.out.println(channel.remoteAddress()); // 定义发送的数据消息 ByteBuf content = Unpooled.copiedBuffer("Hello,Netty!", CharsetUtil.UTF_8); //构建一个http response DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content); // 为响应增加数据类型和长度(content.readableBytes是算出长度) response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes()); // 把响应刷到客户端 [写 和 刷新] channelHandlerContext.writeAndFlush(response); } } // 下面是Channel的一下生命周期,我们重写即可 @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("Channel---用户事件触发"); 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("Channel---捕获异常触发函数"); super.exceptionCaught(ctx, cause); } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { System.out.println("Channel---助手类添加"); super.handlerAdded(ctx); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { System.out.println("Channel---助手类移除"); super.handlerRemoved(ctx); } }
运行:
因为...谷歌浏览器请求了2次,一次是正常,一次是图标icon,所以...
本文来自博客园,作者:咸瑜,转载请注明原文链接:https://www.cnblogs.com/bi-hu/p/16007061.html