package com.pt.utils;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import java.net.URI;
import java.util.Map;
/**
* @author panteng
* @description
* @date 17-3-20.
*/
public class NonBlockHttpClient {
public static EventLoopGroup workerGroup = new NioEventLoopGroup(1);
public static Bootstrap b = new Bootstrap();
public static final EventExecutorGroup executor = new DefaultEventExecutorGroup(2);
static {
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000);
}
public static Object lock = new Object();
/**
* 异步GET请求
*
* @param url
* @param head
* @param handler
* @return
*/
public static Boolean get(String url, Map head, final HttpHandler handler) {
try {
URI uri = new URI(url);
String domain = uri.getHost();
Integer port = uri.getPort() <0 ? 80 : uri.getPort();
DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri.toASCIIString());
if (head == null) {
request.headers().add("Host", domain);
request.headers().add("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:44.0) Gecko/20100101 Firefox/44.0");
request.headers().add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
request.headers().add("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
request.headers().add("Connection", "keep-alive");
request.headers().add("Cache-Control", "max-age=0");
} else {
for (Map.Entry entry : head.entrySet()) {
request.headers().add((String) entry.getKey(), entry.getValue());
}
}
ChannelInitializer channelInitializer = new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
// 客户端接收到的是httpResponse响应,所以要使用HttpResponseDecoder进行解码
socketChannel.pipeline().addLast(new HttpResponseDecoder());
// 客户端发送的是httprequest,所以要使用HttpRequestEncoder进行编码
socketChannel.pipeline().addLast(new HttpRequestEncoder());
socketChannel.pipeline().addLast(executor, new GeneralHandler(handler));
}
};
ChannelFuture f;
synchronized (lock) {
b.handler(channelInitializer);
f = b.connect(domain, port).sync();
}
f.channel().writeAndFlush(request);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static void close() {
try {
executor.shutdownGracefully();
workerGroup.shutdownGracefully();
} catch (Exception e) {
e.printStackTrace();
}
}
}