001: /*
002: * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0-beta1/module-nio/src/examples/org/apache/http/examples/nio/NHttpClient.java $
003: * $Revision: 613298 $
004: * $Date: 2008-01-18 23:09:22 +0100 (Fri, 18 Jan 2008) $
005: *
006: * ====================================================================
007: * Licensed to the Apache Software Foundation (ASF) under one
008: * or more contributor license agreements. See the NOTICE file
009: * distributed with this work for additional information
010: * regarding copyright ownership. The ASF licenses this file
011: * to you under the Apache License, Version 2.0 (the
012: * "License"); you may not use this file except in compliance
013: * with the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing,
018: * software distributed under the License is distributed on an
019: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
020: * KIND, either express or implied. See the License for the
021: * specific language governing permissions and limitations
022: * under the License.
023: * ====================================================================
024: *
025: * This software consists of voluntary contributions made by many
026: * individuals on behalf of the Apache Software Foundation. For more
027: * information on the Apache Software Foundation, please see
028: * <http://www.apache.org/>.
029: *
030: */
031: package org.apache.http.examples.nio;
032:
033: import java.io.IOException;
034: import java.io.InterruptedIOException;
035: import java.net.InetSocketAddress;
036:
037: import org.apache.http.HttpEntity;
038: import org.apache.http.HttpException;
039: import org.apache.http.HttpHost;
040: import org.apache.http.HttpRequest;
041: import org.apache.http.HttpResponse;
042: import org.apache.http.impl.DefaultConnectionReuseStrategy;
043: import org.apache.http.params.BasicHttpParams;
044: import org.apache.http.impl.nio.DefaultClientIOEventDispatch;
045: import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
046: import org.apache.http.message.BasicHttpRequest;
047: import org.apache.http.nio.NHttpConnection;
048: import org.apache.http.nio.protocol.BufferingHttpClientHandler;
049: import org.apache.http.nio.protocol.EventListener;
050: import org.apache.http.nio.protocol.HttpRequestExecutionHandler;
051: import org.apache.http.nio.reactor.ConnectingIOReactor;
052: import org.apache.http.nio.reactor.IOEventDispatch;
053: import org.apache.http.nio.reactor.SessionRequest;
054: import org.apache.http.params.CoreConnectionPNames;
055: import org.apache.http.params.HttpParams;
056: import org.apache.http.params.CoreProtocolPNames;
057: import org.apache.http.protocol.BasicHttpProcessor;
058: import org.apache.http.protocol.HttpContext;
059: import org.apache.http.protocol.ExecutionContext;
060: import org.apache.http.protocol.RequestConnControl;
061: import org.apache.http.protocol.RequestContent;
062: import org.apache.http.protocol.RequestExpectContinue;
063: import org.apache.http.protocol.RequestTargetHost;
064: import org.apache.http.protocol.RequestUserAgent;
065: import org.apache.http.util.EntityUtils;
066:
067: public class NHttpClient {
068:
069: public static void main(String[] args) throws Exception {
070: HttpParams params = new BasicHttpParams();
071: params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
072: .setIntParameter(
073: CoreConnectionPNames.CONNECTION_TIMEOUT, 10000)
074: .setIntParameter(
075: CoreConnectionPNames.SOCKET_BUFFER_SIZE,
076: 8 * 1024).setBooleanParameter(
077: CoreConnectionPNames.STALE_CONNECTION_CHECK,
078: false).setBooleanParameter(
079: CoreConnectionPNames.TCP_NODELAY, true)
080: .setParameter(CoreProtocolPNames.USER_AGENT,
081: "HttpComponents/1.1");
082:
083: final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(
084: 2, params);
085:
086: BasicHttpProcessor httpproc = new BasicHttpProcessor();
087: httpproc.addInterceptor(new RequestContent());
088: httpproc.addInterceptor(new RequestTargetHost());
089: httpproc.addInterceptor(new RequestConnControl());
090: httpproc.addInterceptor(new RequestUserAgent());
091: httpproc.addInterceptor(new RequestExpectContinue());
092:
093: // We are going to use this object to synchronize between the
094: // I/O event and main threads
095: RequestCount requestCount = new RequestCount(3);
096:
097: BufferingHttpClientHandler handler = new BufferingHttpClientHandler(
098: httpproc, new MyHttpRequestExecutionHandler(
099: requestCount),
100: new DefaultConnectionReuseStrategy(), params);
101:
102: handler.setEventListener(new EventLogger());
103:
104: final IOEventDispatch ioEventDispatch = new DefaultClientIOEventDispatch(
105: handler, params);
106:
107: Thread t = new Thread(new Runnable() {
108:
109: public void run() {
110: try {
111: ioReactor.execute(ioEventDispatch);
112: } catch (InterruptedIOException ex) {
113: System.err.println("Interrupted");
114: } catch (IOException e) {
115: System.err.println("I/O error: " + e.getMessage());
116: }
117: System.out.println("Shutdown");
118: }
119:
120: });
121: t.start();
122:
123: SessionRequest[] reqs = new SessionRequest[requestCount
124: .getValue()];
125: reqs[0] = ioReactor.connect(new InetSocketAddress(
126: "www.yahoo.com", 80), null, new HttpHost(
127: "www.yahoo.com"), null);
128: reqs[1] = ioReactor.connect(new InetSocketAddress(
129: "www.google.com", 80), null, new HttpHost(
130: "www.google.ch"), null);
131: reqs[2] = ioReactor.connect(new InetSocketAddress(
132: "www.apache.org", 80), null, new HttpHost(
133: "www.apache.org"), null);
134:
135: // Block until all connections signal
136: // completion of the request execution
137: synchronized (requestCount) {
138: while (requestCount.getValue() > 0) {
139: requestCount.wait();
140: }
141: }
142:
143: System.out.println("Shutting down I/O reactor");
144:
145: ioReactor.shutdown();
146:
147: System.out.println("Done");
148: }
149:
150: static class MyHttpRequestExecutionHandler implements
151: HttpRequestExecutionHandler {
152:
153: private final static String REQUEST_SENT = "request-sent";
154: private final static String RESPONSE_RECEIVED = "response-received";
155:
156: private final RequestCount requestCount;
157:
158: public MyHttpRequestExecutionHandler(
159: final RequestCount requestCount) {
160: super ();
161: this .requestCount = requestCount;
162: }
163:
164: public void initalizeContext(final HttpContext context,
165: final Object attachment) {
166: HttpHost targetHost = (HttpHost) attachment;
167: context.setAttribute(ExecutionContext.HTTP_TARGET_HOST,
168: targetHost);
169: }
170:
171: public void finalizeContext(final HttpContext context) {
172: Object flag = context.getAttribute(RESPONSE_RECEIVED);
173: if (flag == null) {
174: // Signal completion of the request execution
175: synchronized (this .requestCount) {
176: this .requestCount.decrement();
177: this .requestCount.notifyAll();
178: }
179: }
180: }
181:
182: public HttpRequest submitRequest(final HttpContext context) {
183: HttpHost targetHost = (HttpHost) context
184: .getAttribute(ExecutionContext.HTTP_TARGET_HOST);
185: Object flag = context.getAttribute(REQUEST_SENT);
186: if (flag == null) {
187: // Stick some object into the context
188: context.setAttribute(REQUEST_SENT, Boolean.TRUE);
189:
190: System.out.println("--------------");
191: System.out.println("Sending request to " + targetHost);
192: System.out.println("--------------");
193:
194: return new BasicHttpRequest("GET", "/");
195: } else {
196: // No new request to submit
197: return null;
198: }
199: }
200:
201: public void handleResponse(final HttpResponse response,
202: final HttpContext context) {
203: HttpEntity entity = response.getEntity();
204: try {
205: String content = EntityUtils.toString(entity);
206:
207: System.out.println("--------------");
208: System.out.println(response.getStatusLine());
209: System.out.println("--------------");
210: System.out.println("Document length: "
211: + content.length());
212: System.out.println("--------------");
213: } catch (IOException ex) {
214: System.err.println("I/O error: " + ex.getMessage());
215: }
216:
217: context.setAttribute(RESPONSE_RECEIVED, Boolean.TRUE);
218:
219: // Signal completion of the request execution
220: synchronized (this .requestCount) {
221: this .requestCount.decrement();
222: this .requestCount.notifyAll();
223: }
224: }
225:
226: }
227:
228: static class EventLogger implements EventListener {
229:
230: public void connectionOpen(final NHttpConnection conn) {
231: System.out.println("Connection open: " + conn);
232: }
233:
234: public void connectionTimeout(final NHttpConnection conn) {
235: System.out.println("Connection timed out: " + conn);
236: }
237:
238: public void connectionClosed(final NHttpConnection conn) {
239: System.out.println("Connection closed: " + conn);
240: }
241:
242: public void fatalIOException(final IOException ex,
243: final NHttpConnection conn) {
244: System.err.println("I/O error: " + ex.getMessage());
245: }
246:
247: public void fatalProtocolException(final HttpException ex,
248: final NHttpConnection conn) {
249: System.err.println("HTTP error: " + ex.getMessage());
250: }
251:
252: }
253:
254: static class RequestCount {
255:
256: private int value;
257:
258: public RequestCount(int initialValue) {
259: this .value = initialValue;
260: }
261:
262: public int getValue() {
263: return this .value;
264: }
265:
266: public void decrement() {
267: this.value--;
268: }
269:
270: }
271:
272: }
|