001    /*
002     * Copyright (c) 2003, The Regents of the University of California, through
003     * Lawrence Berkeley National Laboratory (subject to receipt of any required
004     * approvals from the U.S. Dept. of Energy). All rights reserved.
005     */
006    package gov.lbl.dsd.sea.nio.demo;
007    
008    import gov.lbl.dsd.sea.Stage;
009    import gov.lbl.dsd.sea.StageManager;
010    import gov.lbl.dsd.sea.nio.AgentEventHandler;
011    import gov.lbl.dsd.sea.nio.NetAgent;
012    import gov.lbl.dsd.sea.nio.event.AdminRequest;
013    import gov.lbl.dsd.sea.nio.event.ChannelRequest;
014    import gov.lbl.dsd.sea.nio.event.ChannelResponse;
015    import gov.lbl.dsd.sea.nio.util.ArrayByteList;
016    
017    import java.io.IOException;
018    import java.net.InetSocketAddress;
019    import java.nio.ByteBuffer;
020    import java.nio.channels.SelectionKey;
021    import java.nio.charset.Charset;
022    
023    /**
024     * Simple echo client; connects to one or more HTTP servers and prints page
025     * output.
026     * <p>
027     * Example usage: fire-java gov.lbl.dsd.sea.nio.demo.HttpClient localhost:8080 www.google.com:80 localhost:9999
028     * 
029     * @author whoschek@lbl.gov
030     * @author $Author: gegles $
031     * @version $Revision: 1.5 $, $Date: 2004/09/16 16:57:15 $
032     */
033    public class HttpClient extends AgentEventHandler {
034    
035            private static final Charset CHARSET = Charset.forName("ISO-8859-1");
036            private int nrChannels = 0;
037    
038            private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
039                            .getLog(HttpClient.class);
040    
041            static public void main(String args[]) throws IOException {
042                    new HttpClient(args);
043            }
044    
045            public HttpClient(String args[]) throws IOException {
046                    NetAgent agent = new NetAgent();
047                    Stage myStage = new StageManager().createStage(this).start();
048    
049                    if (args.length < 1) throw new IllegalArgumentException("usage: java <class> host:port...");
050                    for (int i=0; i < args.length; i++) {
051                            int delim = args[i].indexOf(":");
052                            if (delim < 0) throw new IllegalArgumentException("usage: java <class> host:port...");
053                            String hostName = args[i].substring(0, delim); 
054                            int port = Integer.parseInt(args[i].substring(delim+1, args[i].length()));
055                            agent.addConnectAddress(myStage, new InetSocketAddress(hostName, port));
056                            this.nrChannels++;
057                    }
058    
059                    agent.start();
060            }
061    
062            protected void onClosed(ChannelResponse.Closed rsp) {
063                    log.info("*************got channel closed=" + rsp);
064                    if (rsp.getException() != null) {
065                            log.error(rsp.getException());
066                    }
067                    ArrayByteList readBuffer = (ArrayByteList) rsp.getKey().attachment();
068                    if (readBuffer != null) {
069                            System.out.println("*** fully read bytes  = " + readBuffer);            
070                            System.out.println("*** fully read string = " + readBuffer.toString(CHARSET));
071                    }
072                    if (--nrChannels == 0) {
073                            this.shutDown(rsp);
074                    }
075            }
076    
077            protected void onConnected(ChannelResponse.Connected rsp) {
078                    log.info("*************got connected=" + rsp);
079                    rsp.getKey().attach(new ArrayByteList());
080                    rsp.getAgent().enqueue(
081                                    new ChannelRequest.Register(this.getStage(), rsp.getKey()
082                                                    .channel(), SelectionKey.OP_READ));
083                    ByteBuffer buffer = new ArrayByteList("GET / HTTP/1.0" + "\r\n" + "\r\n", CHARSET).asByteBuffer();
084                    rsp.getAgent().enqueue(
085                                    new ChannelRequest.WriteData(rsp.getKey().channel(), buffer));
086            }
087    
088            protected void onRead(ChannelResponse.Read rsp) {
089                    ArrayByteList readBuffer = (ArrayByteList) rsp.getKey().attachment();
090                    readBuffer.add(rsp.getBuffer());                
091            }
092    
093            protected void onAccepted(ChannelResponse.Accepted rsp) {
094                    throw new UnsupportedOperationException();
095            }
096    
097            protected void onWrite(ChannelResponse.Write rsp) {}
098    
099            protected void onRegistered(ChannelResponse.Registered rsp) {}
100    
101            private void shutDown(ChannelResponse rsp) {
102                    System.out.println("now shutting down...");
103                    this.getStage().stop();
104                    rsp.getAgent().enqueue(new AdminRequest.Stop());
105            }
106    
107    }