Netty(2) – HelloWorld

 

Netty:作用场景。

1)Netty可以基于socket实现远程过程调用(RPC)。

2)Netty可以基于WebSocket实现长连接。

3)Netty可以实现Http的服务器,类似于Jetty,Tomcat等Servlet容器。

————————————————————————————————————————————-

Netty充当Http服务器,我们通过浏览器去访问服务器的资源,服务器端处理完之后给我们返回响应—–Helloworld。

————————————————————————————————————————————-

1)定义一个Server

 1 package com.foreign.netty.helloworld;
 2 
 3 import io.netty.bootstrap.ServerBootstrap; 4 import io.netty.channel.ChannelFuture; 5 import io.netty.channel.EventLoopGroup; 6 import io.netty.channel.nio.NioEventLoopGroup; 7 import io.netty.channel.socket.nio.NioServerSocketChannel; 8 9 /** 10 * Created with IDEA 11 * author:foreign 12 * Date:2018/12/25 13 * Time:23:21 14 */ 15 public class TestServer { 16 public static void main(String[] args) throws InterruptedException { 17 /** 18 * 两个事件循环组(死循环) boos接受连接并发送给worker 19 */ 20 EventLoopGroup bossLooper = new NioEventLoopGroup(); 21 EventLoopGroup workerLooper = new NioEventLoopGroup(); 22 23 try { 24 /** 25 * ServerBootstrap 服务端启动 26 * NioServerSocketChannel 通道(反射) 27 */ 28 ServerBootstrap serverBootstrap = new ServerBootstrap(); 29 serverBootstrap.group(bossLooper, workerLooper).channel(NioServerSocketChannel.class).childHandler(new TestServerInitializer()); 30 31 ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); 32  channelFuture.channel().closeFuture().sync(); 33 } finally { 34  bossLooper.shutdownGracefully(); 35  workerLooper.shutdownGracefully(); 36  } 37  } 38 }

2)定义一个Initializer

 1 package com.foreign.netty.helloworld;
 2 
 3 import io.netty.channel.ChannelInitializer; 4 import io.netty.channel.ChannelPipeline; 5 import io.netty.channel.socket.SocketChannel; 6 import io.netty.handler.codec.http.HttpServerCodec; 7 8 /** 9 * Created with IDEA 10 * author:foreign 11 * Date:2018/12/25 12 * Time:23:32 13 */ 14 public class TestServerInitializer extends ChannelInitializer<SocketChannel> { 15 16 /** 17 * 子处理器, channel被注册好,会被自动创建 18 * @param ch 19 * @throws Exception 20 */ 21  @Override 22 protected void initChannel(SocketChannel ch) throws Exception { 23 ChannelPipeline pipeline = ch.pipeline(); 24 //编解码 25 pipeline.addLast("httpServerCodec",new HttpServerCodec()); 26 //自己定义的handler 27 pipeline.addLast("testHttpServerHandler",new TestHttpServerHandler()); 28 29  } 30 }

3)定义一个Handler

1 package com.foreign.netty.helloworld;
 2 
 3 import io.netty.buffer.ByteBuf;
 4 import io.netty.buffer.Unpooled;
 5 import io.netty.channel.ChannelHandlerContext;
 6 import io.netty.channel.SimpleChannelInboundHandler;
 7 import io.netty.handler.codec.http.*;
 8 import io.netty.util.CharsetUtil;
 9 
10 import java.net.URI;
11 
12 /**
13  * Created with IDEA
14  * author:foreign
15  * Date:2018/12/25
16  * Time:23:34
17  */
18 public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
19     /**
20      * 把结果返回给客户端(回调)
21      */
22     @Override
23     protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
24         if (msg instanceof HttpRequest) {
25 
26             HttpRequest httpRequest = (HttpRequest) msg;
27 
28             //获取请求的方法类型
29             System.out.println(httpRequest.method().name());
30 
31             URI uri = new URI(httpRequest.uri());
32             if("/favicon.io".equals(uri)) {
33                 System.out.println("请求了favicon.io 图标");
34                 return;
35             }
36 
37             ByteBuf content = Unpooled.copiedBuffer("Hello Netty", CharsetUtil.UTF_8);
38             FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
39             response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
40             response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
41 
42             ctx.writeAndFlush(response);
43 
44             ctx.channel().close();
45         }
46     }
47 }

4)gradle的配置

plugins {
    id ‘java‘
}

group ‘com.foreign‘
version ‘1.0-SNAPSHOT‘

apply plugin: ‘java‘

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    implementation ‘io.netty:netty-all:4.1.10.Final‘
    testCompile (
            "junit:junit:4.11"
    )
}

5)运行结果:运行server,并访问该地址。

6)总结:

1)在TestServer类中,启动一个ServerBootStrap的服务器,里面有两个事件循环组,并且通childHandler关联处理器。

2)在TestServerInitializer中加载netty内置的handler和自己的handler。

3)在TestHttpServerHandler中返回数据到客户端。