1 package com.foxinmy.weixin4j.http.support.netty;
2
3 import io.netty.bootstrap.Bootstrap;
4 import io.netty.channel.ChannelInitializer;
5 import io.netty.channel.ChannelOption;
6 import io.netty.channel.ChannelPipeline;
7 import io.netty.channel.EventLoopGroup;
8 import io.netty.channel.nio.NioEventLoopGroup;
9 import io.netty.channel.socket.SocketChannel;
10 import io.netty.channel.socket.nio.NioSocketChannel;
11 import io.netty.handler.codec.http.HttpClientCodec;
12 import io.netty.handler.codec.http.HttpContentDecompressor;
13 import io.netty.handler.codec.http.HttpObjectAggregator;
14 import io.netty.handler.codec.http.HttpResponseDecoder;
15 import io.netty.handler.stream.ChunkedWriteHandler;
16 import io.netty.handler.timeout.ReadTimeoutHandler;
17
18 import java.util.Map;
19 import java.util.concurrent.TimeUnit;
20
21 import com.foxinmy.weixin4j.http.HttpClient;
22 import com.foxinmy.weixin4j.http.HttpParams;
23 import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
24
25
26
27
28
29
30
31
32
33 public class Netty4HttpClientFactory extends HttpClientFactory {
34 private volatile Bootstrap bootstrap;
35 private EventLoopGroup eventLoopGroup;
36 private Map<ChannelOption<?>, ?> options;
37
38 public Netty4HttpClientFactory() {
39 this(new NioEventLoopGroup(
40 Runtime.getRuntime().availableProcessors() * 4));
41 }
42
43 public Netty4HttpClientFactory(EventLoopGroup eventLoopGroup) {
44 this.eventLoopGroup = eventLoopGroup;
45 }
46
47 public Netty4HttpClientFactory setOptions(Map<ChannelOption<?>, ?> options) {
48 if (options == null) {
49 throw new IllegalArgumentException("'options' must not be empty");
50 }
51 this.options = options;
52 return this;
53 }
54
55 private Bootstrap getBootstrap(final HttpParams params) {
56 if (bootstrap == null) {
57 bootstrap = new Bootstrap();
58 bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)
59 .handler(new ChannelInitializer<SocketChannel>() {
60 @Override
61 protected void initChannel(SocketChannel channel)
62 throws Exception {
63 ChannelPipeline pipeline = channel.pipeline();
64 if (params != null) {
65 channel.config().setConnectTimeoutMillis(
66 params.getConnectTimeout());
67 if (options != null) {
68 channel.config().setOptions(options);
69 }
70 pipeline.addLast(new ReadTimeoutHandler(params
71 .getReadTimeout(),
72 TimeUnit.MILLISECONDS));
73 }
74 pipeline.addLast(new HttpClientCodec());
75 pipeline.addLast(new HttpContentDecompressor());
76 pipeline.addLast(new ChunkedWriteHandler());
77 pipeline.addLast(new HttpResponseDecoder());
78 pipeline.addLast(new HttpObjectAggregator(
79 Integer.MAX_VALUE));
80 }
81 });
82 }
83 return bootstrap;
84 }
85
86 @Override
87 public HttpClient newInstance(HttpParams params) {
88 return new Netty4HttpClient(getBootstrap(params), params);
89 }
90 }