服务启动端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.jhj.netty.http;

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 TestServer {


public static void main(String[] args) throws Exception{

EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();

try{

ServerBootstrap serverBootstrap = new ServerBootstrap();

serverBootstrap.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new TestServerInitializer());
ChannelFuture channelFuture = serverBootstrap.bind(7000).sync();

channelFuture.channel().closeFuture().sync();
}finally {

bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}

服务初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.jhj.netty.http;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;

public class TestServerInitializer extends ChannelInitializer<SocketChannel> {


@Override
protected void initChannel(SocketChannel ch) throws Exception {

//向管道加入处理器

//得到管道
ChannelPipeline pipeline = ch.pipeline();

//加入netty 提供的http编解码器 heetServerCodec codec=>{code+decoder}

pipeline.addLast("MyHttpServerCodec",new HttpServerCodec());

//增加一个自定义的handler
pipeline.addLast("MyTestHttpServerHandler",new TestHttpServerHandler());


}
}

服务处理器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.jhj.netty.http;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;

import java.net.URI;

/*
SimpleChannelInboundHandler 是ChannelInboundHandler子类
HttpObject 表示客户端和服务器端相互通讯的数据被封装成 HttpObject
*/
public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {



//当有读取事件是会触发函数
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {


//判断msg是不是 httpRequest请求
if (msg instanceof HttpRequest) {



//由于Http不是长连接 每次用完后会断掉 一次请求的 浏览器和channel 一一对应 channel和piepeline 一一对应
System.out.println("pipeline hashcode"+ctx.pipeline().hashCode()+"TestHttpServerHandler hash="+this.hashCode());

System.out.println("msg 类型=" + msg.getClass());

System.out.println("客户端地址" + ctx.channel().remoteAddress());

//通过url 过滤指定资源
//获取到 msg资源的url
HttpRequest httpRequest=(HttpRequest) msg;
URI uri = new URI(httpRequest.uri());

if ("/favicon.ico".equals(uri.getPath())){

System.out.println("你请求了 favicon.ico 不做响应");
return;
}


//回复信息给浏览器
ByteBuf content = Unpooled.copiedBuffer("hello,我是服务器", CharsetUtil.UTF_8);

//构造一个http的响应 httpResponse
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);

response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain;charset=UTF-8");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());

ctx.writeAndFlush(response);
}

}
}

作者声明

1
如有问题,欢迎指正!