6

AsyncHttpClient का उपयोग Netty प्रदाता के साथ मुख्य प्रोग्राम को समाप्त करने से रोक देगा जब हम एक एसिंक्रोनस अनुरोध निष्पादित करते हैं। उदाहरण के लिए निम्नलिखित कार्यक्रम println के बाद समाप्त हो जाता है, या नहीं, चाहे प्रदाता JDKAsyncHttpProvider या NettyAsyncHttpProvider है पर निर्भर करता है:एसिंक्रोनस एचटीपी अनुरोध के लिए नेटटी के साथ AsyncHttpClient को कैसे बंद करें?

public class Program { 
    public static CompletableFuture<Response> getDataAsync(String uri) { 
     final AsyncHttpClient asyncHttpClient = new AsyncHttpClient(); 
     final CompletableFuture<Response> promise = new CompletableFuture<>(); 
     asyncHttpClient 
      .prepareGet(uri) 
      .execute(new AsyncCompletionHandler<Response>(){ 
       @Override 
       public Response onCompleted(Response resp) throws Exception { 
        promise.complete(resp); 
        asyncHttpClient.close(); // ??? Is this correct ???? 
        return resp; 
       } 
      }); 
     return promise; 
    } 

    public static void main(String [] args) throws Exception { 
     final String uri = "…"; 
     System.out.println(getDataAsync(uri).get()); 
    } 
} 

बारे AsynHttpClient प्रलेखन राज्यों:

AHC एक अमूर्त परत है जो नंगे जेडीके, नेटटी और ग्रीज़ली के शीर्ष पर काम कर सकता है। ध्यान दें कि जेडीके कार्यान्वयन बहुत सीमित है और आपको वास्तव में अन्य वास्तविक प्रदाताओं का उपयोग करना चाहिए।

नेटटी के साथ AsyncHttpClient का उपयोग करने के लिए हमें जावा क्लास पथ में संबंधित लाइब्रेरी को शामिल करने की आवश्यकता है। तो, हम निम्नलिखित वर्ग पथ विन्यास में से एक के साथ पिछले Program चला सकते हैं Netty, या नहीं का उपयोग करें:

  • -cp .;async-http-client-1.9.24.jar;netty-3.10.3.Final.jar;slf4j-api-1.7.12.jar का उपयोग करेगा NettyAsyncHttpProvider
  • -cp .;async-http-client-1.9.24.jar;slf4j-api-1.7.12.jarJDKAsyncHttpProvider

का उपयोग करेगा हम और क्या चाहिए Netty प्रदाता का सही ढंग से उपयोग करने के लिए करते हैं? उदाहरण के लिए, मैं AsyncCompletionHandler में बंद कर रहा हूं। क्या वो सही है?

क्या देखा गया व्यवहार बदलने के लिए कोई विन्यास है?

+0

'AsyncHttpClient' धागा सुरक्षित नहीं है:

यहाँ निशान है? प्रत्येक विधि आमंत्रण पर नया न बनाएं। –

+0

यदि आप क्लाइंट को बाद में बंद करने का प्रयास करते हैं, उदा। 'तब स्वीकार करें' के बाद, क्या आपका आवेदन समाप्त हो जाएगा? – ZhongYu

+0

नहीं बंद करना, या नहीं, asyncHttpClient का परिणामी व्यवहार में कोई प्रभाव नहीं है। –

उत्तर

4

नेटटी प्रदाता का उपयोग करके और डीबगर में इसके माध्यम से कदम उठाने के बाद, मुझे लगता है कि कॉलबैक के अंदर asyncHttpClient.close() को कॉल करने से NioSocketChannelFactory.releaseExternalResources() विफल हो जाता है जब यह शट डाउन करने का प्रयास करता है। एक अपवाद फेंक दिया जाता है, और यह संभवतः गैर डिमन थ्रेड को बनाए रखने की संभावना है, और वीएम को बाहर निकलने से रोकता है। WARN पर अपवाद फेंक दिया गया है, इसलिए आप शायद इसे नहीं देख रहे हैं (यदि आप क्लासपाथ में slf4j-log4j12-1.7.7.jar जोड़ते हैं तो आपको इसे देखना चाहिए)। तो आप कॉल बैक में क्लोज़() को कॉल नहीं कर सकते (और आपको किसी भी अनुरोध निष्पादन के बाद इसे बंद करने की आवश्यकता नहीं है)।

WARN [New I/O worker #1] (NettyAsyncHttpProvider.java:79) - Unexpected error on close 
java.lang.IllegalStateException: Must not be called from a I/O-Thread to prevent deadlocks! 
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.shutdown(AbstractNioSelector.java:415) 
at org.jboss.netty.channel.socket.nio.NioWorker.shutdown(NioWorker.java:36) 
at org.jboss.netty.channel.socket.nio.AbstractNioWorkerPool.shutdown(AbstractNioWorkerPool.java:142) 
at org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory.releaseExternalResources(NioClientSocketChannelFactory.java:225) 
at com.ning.http.client.providers.netty.channel.ChannelManager.close(ChannelManager.java:355) 
at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.close(NettyAsyncHttpProvider.java:70) 
at com.ning.http.client.AsyncHttpClient.close(AsyncHttpClient.java:336) 
at com.cie.program.Program$1.onCompleted(Program.java:23) 
संबंधित मुद्दे