java netty http https pool 例子
java netty http https pool 例子
1.废话不多说,写出这个netty 的例子还是花了我不少时间的,,期间遇到各种问题折腾了蛮久的。
netty 的核心组件我这里就不详解了,,有很多讲的很好的文章大家可以在百度搜索下
首先上一个netty 最简单的例子
boot = new Bootstrap();
// 绑定管理分组
boot.group(new NioEventLoopGroup());
// 这里是设置Channel 类型,一般用 NioSocketChannel 比较多,毕竟netty异步玩的6
boot.channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true);;
boot.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel arg0) throws Exception {
// 将多个消息转为一个full
arg0.pipeline().addLast(new HttpObjectAggregator(65536));
// 添加请求编码
arg0.pipeline().addLast(new HttpRequestEncoder());
// 添加请求解码
arg0.pipeline().addLast(new HttpResponseDecoder());
}
});
其实写代码的时候最重要的是 ChannelHandler 所有的数据都是经过 ChannelHandler 处理的,
pipeline 的作用是将所有的 ChannelHandler 连在一起形成一个链表
我们现在抛开netty的io 管理 不谈,就只管pipeline
比如 现在有一个http请求
-
“`
——————————– 分割线————-
HTTP/1.1 200 OK
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 267
Content-Type: text/javascript; charset=gbk
Date: Thu, 31 Aug 2017 15:01:56 GMT
Expires: Thu, 31 Aug 2017 16:01:56 GMT
Server: suggestion.baidu.zbb.df
———- 下面是http响应body
jQuery110205708391915849484_1504191642334({“q”:”hah”,”p”:false,”bs”:”“,”csor”:”3”,”status”:0,”g”:[ {
“q”: “¹þ¹þmx”, “t”: “n”, “st”: { “q”: “¹þ¹þmx”, “new”: 0 } }, { “q”: “¹þ¹þÉÙ¶ù”, “t”: “n”, “st”: { “q”
-
“¹þ¹þÉÙ¶ù”, “new”: 0 } }, { “q”: “¹þ¹þ”, “t”: “n”, “st”: { “q”: “¹þ¹þ”, “new”: 0 } }, { “q”: “haha”
, “t”: “n”, “st”: { “q”: “haha”, “new”: 0 } }, { “q”: “¹þ¹þ¶¯Âþ”, “t”: “n”, “st”: { “q”: “¹þ¹þ¶¯Âþ”,
“new”: 0 } }, { “q”: “¹þ¹þ¹þ”, “t”: “n”, “st”: { “q”: “¹þ¹þ¹þ”, “new”: 0 } }, { “q”: “¹þ¹þ¾µ”, “t”:
“n”, “st”: { “q”: “¹þ¹þ¾µ”, “new”: 0 } }, { “q”: “hahaha”, “t”: “n”, “st”: { “q”: “hahaha”, “new”: 0
} }, { “q”: “¹þ¹þ¹þ¹þàÔ, “t”: “n”, “st”: { “q”: “¹þ¹þ¹þ¹þàÔ, “new”: 0 } }, { “q”: “¹þ¹þ¹þ±íÇé°ü”,
“t”: “n”, “st”: { “q”: “¹þ¹þ¹þ±íÇé°ü”, “new”: 0 } } ],”s”:[“¹þ¹þmx”,”¹þ¹þÉÙ¶ù”,”¹þ¹þ”,”haha”,”¹þ¹þ¶
¯Âþ”,”¹þ¹þ¹þ”,”¹þ¹þ¾µ”,”hahaha”,”¹þ¹þ¹þ¹þàÔ,”¹þ¹þ¹þ±íÇé°ü”]});你好,我是http请求body
“`——————————– 分割线————-
上面是一个完整的http请求,我们在使用时一般只需要body 那么问题来了,我们这里用的io 是 NioSocketChannel 它其实是一个tcp 连接,未经处理返回的是一个byte数组,我们不能直接使用,这个时候就需要用到 ChannelHandler 来处理了!因为是服务端返回的数据我们需要解码,这里用的是 HttpResponseDecoder 来处理。HttpResponseDecoder 能将它解成handler 和 body两部分,这样我们就可以像httpclient一样来使用了!
同样我们发起http请求也需要 ChannelHandler 来帮我们将请求的内容进行一个组装 (HttpRequestEncoder)这样我们基本的http请求和http响应就处理完成了,
但是我们现在还没有对响应的数据进行接收。同样我们接收数据也需要用到ChannelHandler 但是我们没必要直接去实现ChannelHandler 接口 我们可以继承 ChannelInboundHandlerAdapter 在ChannelInboundHandlerAdapter 中帮我们做了很多处理工作,我们只需要关心基本的接收数据就可以了
—————————- 分割线
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof HttpResponse) {
HttpResponse response = (HttpResponse) msg;
List<Map.Entry<String, String>> headresList = response.headers().entries();
for (Map.Entry<String, String> h : headresList){
result.handles.put(h.getKey(), h.getValue());
}
}
if (msg instanceof HttpContent) {
HttpContent content = (HttpContent) msg;
ByteBuf buf = content.content();
int bodyLength = ( result.body != null ? result.body.length : 0);
byte[] tempBs = new byte[buf.readableBytes() + bodyLength];
if (tempBs.length != bodyLength){
if ( bodyLength > 0){
System.arraycopy(result.body , 0 , tempBs , 0 , bodyLength);
}
buf.readBytes(tempBs ,bodyLength , buf.readableBytes() );
result.body = tempBs;
}
// 如果是最后一个,,释放客户端
if(msg instanceof LastHttpContent){
result.completeBody();
client.release(ctx.channel(), uri);
}
}
}
————————– 分割线
其中 channelRead 是用来接收数据的,但是channelRead可能会被调用多次,比如 http响应数据至少会被调用两次,第一次是 HttpResponse里面主要包含响应头
第二次是 HttpContent 响应数据 ,有一点要注意 HttpContent 可能分为几次返回 我们可以使用 LastHttpContent 来判断是否是最后一次
netty中响应数据是异步的。我们需要用异步的方式处理
下面是我们使用时简单处理逻辑图
总之一点,netty中所有的操作都是异步的,不管是 创建链接,发送数据,接收数据都是会异步放在线程池处理,这样就可以使用很少的线程资源来管理大量io连接
具体代码请看 src\xiaoa\java\netty\HttpClientUtils.java (https://git.oschina.net/xiaoa1/java1.7Dome/tree/master/src/xiaoa/java/netty)
一切都以 HttpClientUtils.java 为开头
推荐阅读
-
Java Netty HTTP服务实现过程解析
-
Java获取http和https网址对应html数据实例
-
Java 和 HTTP 的那些事之 HTTPS 和 证书
-
Java用HttpClient4发送http/https协议get/post请求,发送map,json,xml,txt数据
-
自己用java写一个http和https代理服务器
-
分享一个Java工具类:内含发起http和https的GET或POST请求
-
proxyme——java NIO实现的http代理,支持https
-
JAVA实现http/https的Post、Get、代理访问请求
-
java netty http https pool 例子
-
Java如何获取http和https网址对应html数据(附代码)