上一篇【第41篇】Netty开发HTTP服务——打造轻量级Web服务器 下一篇【第43篇】Netty WebSocket实战——轻松实现实时双向通信
一、HTTP客户端Pipeline
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new HttpClientCodec()); // 客户端编解码
ch.pipeline().addLast(new HttpObjectAggregator(65536));
ch.pipeline().addLast(new HttpClientHandler());
}
});
注:客户端使用HttpClientCodec,服务端使用HttpServerCodec。
二、异步HTTP客户端
public class AsyncHttpClient {
public static void get(EventLoopGroup group, String host, int port, String path) {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new HttpClientCodec());
ch.pipeline().addLast(new HttpObjectAggregator(65536));
ch.pipeline().addLast(new ResponseHandler());
}
});
b.connect(host, port).addListener((ChannelFuture f) -> {
if (f.isSuccess()) {
FullHttpRequest req = new DefaultFullHttpRequest(HTTP_1_1, GET, path);
req.headers().set(HOST, host);
req.headers().set(CONNECTION, CLOSE);
f.channel().writeAndFlush(req);
}
});
}
static class ResponseHandler extends SimpleChannelInboundHandler<FullHttpResponse> {
protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse resp) {
System.out.println("Status: " + resp.status());
System.out.println("Body: " + resp.content().toString(UTF_8));
ctx.close();
}
}
}
三、连接池复用
// 建立Channel连接池,复用连接
public class HttpConnectionPool {
private final Bootstrap b;
private final Queue<Channel> pool = new ConcurrentLinkedQueue<>();
public Future<Channel> acquire(EventLoop executor) {
Channel ch = pool.poll();
if (ch != null && ch.isActive()) {
return executor.newSucceededFuture(ch);
}
return b.connect();
}
public void release(Channel ch) {
if (ch.isActive()) {
pool.offer(ch); // 归还连接
}
}
}
四、实现简单HTTP爬虫
public class SimpleCrawler {
public static void main(String[] args) throws Exception {
EventLoopGroup group = new NioEventLoopGroup(4);
List<String> urls = Arrays.asList(
"http://example.com/page1",
"http://example.com/page2",
"http://example.com/page3"
);
for (String url : urls) {
get(group, url); // 并发发送请求
}
Thread.sleep(5000);
group.shutdownGracefully();
}
public static void get(EventLoopGroup group, String url) {
URI uri = URI.create(url);
AsyncHttpClient.get(group, uri.getHost(),
uri.getPort() == –1 ? 80 : uri.getPort(), uri.getPath());
}
}
五、总结
| 编解码 | HttpClientCodec |
| 聚合 | HttpObjectAggregator |
| 异步 | addListener回调 |
| 连接池 | ChannelPool复用连接 |
上一篇【第41篇】Netty开发HTTP服务——打造轻量级Web服务器 下一篇【第43篇】Netty WebSocket实战——轻松实现实时双向通信



