2012-03-16 7 views
8

के साथ असीमित HTTP क्लाइंट मैं नेटटी के लिए नया हूं और अभी भी अपना रास्ता खोजने के लिए स्ट्रिंग कर रहा हूं। मैं एक http क्लाइंट बनाना चाहता हूं जो असीमित रूप से काम करता है। http के नेटटी उदाहरण केवल दिखाते हैं कि आईओ ऑपरेशंस के लिए कैसे इंतजार करना है, और ऐडलिस्टर का उपयोग कैसे करें, और इसलिए मैं इसे पिछले कुछ दिनों से समझने की कोशिश कर रहा हूं।नेटी

मैं एक अनुरोध कक्षा बनाने की कोशिश कर रहा हूं जो अनुरोध के सभी अलग-अलग राज्यों को जोड़ने, डेटा भेजने, प्रतिक्रिया को संभालने और फिर कनेक्शन को बंद करने से संभाल लेगा। ऐसा करने के लिए कि मेरी कक्षा सरलChannelUpstreamHandler बढ़ाती है और चैनलफ्यूचर लिस्टर लागू करती है। मैं एक चैनलपाइपलाइन फैक्टरी का उपयोग करता हूं जो (इस) उदाहरण को कक्षा (एक सरलChannelUpstreamHandler) के रूप में पाइपलाइन पर एक हैंडलर के रूप में जोड़ता है। तब operationComplete विधि

this.state = State.Connecting; 
this.clientBootstrap.connect(this.address).addListener(this); 

:

@Override 
public void operationComplete(ChannelFuture future) throws Exception { 
    State oldState = this.state; 

    if (!future.isSuccess()) { 
     this.status = Status.Failed; 
     future.getChannel().disconnect().addListener(this); 
    } 
    else if (future.isCancelled()) { 
     this.status = Status.Canceled; 
     future.getChannel().disconnect().addListener(this); 
    } 
    else switch (this.state) { 
     case Connecting: 
      this.state = State.Sending; 
      Channel channel = future.getChannel(); 
      channel.write(this.createRequest()).addListener(this); 
      break; 

     case Sending: 
      this.state = State.Disconnecting; 
      future.getChannel().disconnect().addListener(this); 
      break; 

     case Disconnecting: 
      this.state = State.Closing; 
      future.getChannel().close().addListener(this); 
      break; 

     case Closing: 
      this.state = State.Finished; 
      break; 
    } 
    System.out.println("request operationComplete start state: " + oldState + ", end state: " + this.state + ", status: " + this.status); 
} 

private HttpRequest createRequest() { 
    String url = this.url.toString(); 

    HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url); 
    request.setHeader(HttpHeaders.Names.HOST, this.url.getHost()); 
    request.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); 
    request.setHeader(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP); 

    return request; 
} 

वर्ग भी ओवरराइड करता है messageReceived विधि:

@Override 
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { 
    System.out.println("messageReceived"); 
    HttpResponse response = (HttpResponse) e.getMessage(); 

    ChannelBuffer content = response.getContent(); 
    if (content.readable()) { 
     System.out.println("CONTENT: " + content.toString(CharsetUtil.UTF_8)); 
    } 
} 

कनेक्शन इस तरह बनाई गई है समस्या यह है कि मैं इस आउटपुट प्राप्त है:

request operationComplete start state: Connecting, end state: Sending, status: Unknown 
request operationComplete start state: Sending, end state: Disconnecting, status: Unknown 
request operationComplete start state: Closing, end state: Finished, status: Unknown 
request operationComplete start state: Disconnecting, end state: Finished, status: Unknown 

आप देख सकते हैं messageReceived की किसी कारण से क्रियान्वित नहीं किया जा रहा है, भले ही पाइप लाइन कारखाने पाइप लाइन के लिए इस वर्ग के उदाहरण कहते हैं।

कोई विचार जो मैं यहां याद कर रहा हूं? धन्यवाद।


संपादित

मैं अंत में @JestanNirojan की मदद करने के लिए इस काम कर धन्यवाद प्राप्त करने के लिए, इस मामले में कोई समाधान में रुचि होगी कामयाब:

public class ClientRequest extends SimpleChannelUpstreamHandler { 

    .... 

    public void connect() { 
     this.state = State.Connecting; 
     System.out.println(this.state); 
     this.clientBootstrap.connect(this.address); 
    } 

    @Override 
    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { 
     this.state = State.Sending; 
     System.out.println(this.state); 
     ctx.getChannel().write(this.createRequest()); 
    } 

    @Override 
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { 
     HttpResponse response = (HttpResponse) e.getMessage(); 

     ChannelBuffer content = response.getContent(); 
     if (content.readable()) { 
      System.out.println("CONTENT: " + content.toString(CharsetUtil.UTF_8)); 
     } 

     this.state = State.Disconnecting; 
     System.out.println(this.state); 
    } 

    @Override 
    public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { 
     this.state = State.Closing; 
     System.out.println(this.state); 
    } 

    @Override 
    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { 
     this.state = State.Finished; 
     System.out.println(this.state); 
    } 

    private HttpRequest createRequest() { 
     String url = this.url.toString(); 

     HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url); 
     request.setHeader(HttpHeaders.Names.HOST, this.url.getHost()); 
     request.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); 
     request.setHeader(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP); 

     return request; 
    } 
} 
+0

पूर्ण HttpResponse HttpResponse है या एक टुकड़ा हो सकता है?मेरे पास 1000 भाग वापस आ रहे हैं और एक घटना प्रति चंक चाहते हैं या स्मृति मेमोरी के परिणामस्वरूप विस्फोट हो जाएगी। –

+0

HttpResponse पूर्ण प्रतिक्रिया है, जहां तक ​​मुझे पता है आप इसे खंडित नहीं कर सकते हैं। आपको तब कम जाना चाहिए, शायद [HttpResponseDecoder] (http://static.netty.io/3.5/api/org/jboss/netty/handler/codec/http/HttpResponseDecoder.html) के साथ। –

+0

यदि आप खंडन में अंतर नहीं रखते हैं तो यहां हल्के http क्लाइंट का उपयोग करें @ https://github.com/arungeorge81/netty-http-client –

उत्तर

3

आप करने के लिए एक ChannelFutureListener उपयोग कर रहे हैं चैनल में सभी परिचालन करें (जो खराब है), और भविष्य के श्रोता को उन चैनल संचालन को कॉल करने के तुरंत बाद निष्पादित किया जाएगा।

समस्या यह है कि संदेश भेजने के बाद, चैनल तुरंत डिस्कनेक्ट हो जाता है और हैंडलर प्रतिक्रिया संदेश प्राप्त नहीं कर सकता जो बाद में आता है।

 ........ 
    case Sending: 
     this.state = State.Disconnecting; 
     future.getChannel().disconnect().addListener(this); 
     break; 
     ........ 

आपको चैनल भविष्य के धागे को बिल्कुल अवरुद्ध नहीं करना चाहिए। सबसे अच्छा तरीका सरलChannelUpstreamHandler के

channelConnected(..) {} 
    messageReceived(..) {} 
    channelDisconnected(..) {} 

विधियों और उन घटनाओं पर प्रतिक्रिया करता है। आप राज्य को उस हैंडलर में भी रख सकते हैं।

+1

ओह। वह आसान था। जानकारी के लिए बहुत बहुत धन्यवाद, मेरी इच्छा है कि नेटटी के पास इस पर बेहतर दस्तावेज था। –

संबंधित मुद्दे