जावा HTTP क्लाइंट रिक्वेस्ट टाइमआउट के साथ


91

मैं अपने क्लाउड में कई सर्वरों के लिए BIT (परीक्षण में निर्मित) बनाना चाहूंगा। मुझे बड़े टाइमआउट पर विफल होने के लिए अनुरोध की आवश्यकता है।

मुझे जावा के साथ यह कैसे करना चाहिए?

नीचे की तरह कुछ कोशिश करने से काम नहीं लगता है।

public class TestNodeAliveness {
 public static NodeStatus nodeBIT(String elasticIP) throws ClientProtocolException, IOException {
  HttpClient client = new DefaultHttpClient();
  client.getParams().setIntParameter("http.connection.timeout", 1);

  HttpUriRequest request = new HttpGet("http://192.168.20.43");
  HttpResponse response = client.execute(request);

  System.out.println(response.toString());
  return null;
 }


 public static void main(String[] args) throws ClientProtocolException, IOException {
  nodeBIT("");
 }
}

- संपादित करें: स्पष्ट करें कि किस पुस्तकालय का उपयोग किया जा रहा है -

मैं अपाचे से httpclient का उपयोग कर रहा हूं, यहां प्रासंगिक pom.xml अनुभाग है

 <dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.0.1</version>
   <type>jar</type>
 </dependency>

आप सभी HTTP कार्यक्षमता के लिए किस पुस्तकालय का उपयोग कर रहे हैं?
नोजो

टिप्पणी के लिये आपका धन्यवाद। मैंने अपनी पोस्ट अपडेट कर दी है।
मैक्सिम वीक्स्लर

जवाबों:


119
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

...

    // set the connection timeout value to 30 seconds (30000 milliseconds)
    final HttpParams httpParams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
    client = new DefaultHttpClient(httpParams);

1
यह क्या करता है? इसका क्या समय निर्धारित होता है? कृपया stackoverflow.com/questions/3000767/…
मैक्सिम वीक्स्लर

84
अपाचे के HttpClient में दो अलग-अलग टाइमआउट हैं: एक टीसीपी कनेक्शन स्थापित करने के लिए कितने समय तक इंतजार करना है, और डेटा के बाद के बाइट के लिए कितने समय तक इंतजार करना है। HttpConnectionParams.setConnectionTimeout () पूर्व है, HttpConnectionParams.setSoTimeout () उत्तरार्द्ध है।
बेवोलिओटी

7
डिफ़ॉल्ट टाइमआउट क्या है? क्या यह 0 = अनंत है?
टोबिया

1
http.connection.timeout पूर्णांक संबंध स्थापित होने तक का समय। शून्य के मान का अर्थ है कि टाइमआउट का उपयोग नहीं किया गया है।
मैवरॉयड

26
भविष्य के पाठकों के लिए: यह ध्यान दिया जाना चाहिए कि यहाँ संदर्भित कक्षाएं अब पदावनत हो गई हैं (2016-07-05 के अनुसार), हालांकि यह संभवतः एक अच्छा उत्तर था जब इसे 2010 में पोस्ट किया गया था। इस उत्तर को देखें: stackoverflow.com/a/ 19153314/192801 कुछ अधिक वर्तमान के लिए।
FrustratedWithFormsDesigner

125

यदि आप Http क्लाइंट संस्करण 4.3 और इसके बाद के संस्करण का उपयोग कर रहे हैं, तो आपको इसका उपयोग करना चाहिए:

RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).build();
HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();

4
धन्यवाद! मैंने 20 मिनट कम से कम यह पता लगाने की कोशिश में बिताए कि आपका जवाब खोजने से पहले ऐसा करने के लिए हटाए गए आदेशों से कैसे छुटकारा पाया जाए।
vextorspace

भूल हो गई SocketTimeout। इसके अलावा, क्या "डिफ़ॉल्ट" का अर्थ है कि यह सभी के लिए डिफ़ॉल्ट HttpClientहै जो HttpClientBuilderबनाने () build()विधि के माध्यम से देगा ? या सिर्फ उन लोगों के माध्यम से जो गुजरते हैं setDefaultRequestConfig(requestConfig)? क्या मैं समझ रहा हूं?
ADTC

@ADTC आपका सवाल थोड़ा भ्रमित करने वाला है :)। डिफ़ॉल्ट अनुरोध कॉन्फ़िगरेशन का उपयोग सभी HttpPost, HttpGet, ... केवल 'HttpClient' का उपयोग करके किया जाएगा। यदि आपने एक और HttpClient उदाहरण बनाया है, तो इस अनुरोध को उस क्लाइंट के साथ उपयोग नहीं किया जाएगा।
थंडर

35

HttpParams नई Apache HTTPClient लाइब्रेरी में पदावनत है। लाज द्वारा प्रदान किए गए कोड का उपयोग करने से पदावनति चेतावनियाँ आती हैं।

मैं आपके HttpGet या HttpPost उदाहरण के बजाय RequestConfig का उपयोग करने का सुझाव देता हूं:

final RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build();
httpPost.setConfig(params);

"उपरोक्त कोड का उपयोग करना" << SO एक मंच नहीं है और उत्तर कई कारकों के कारण ऊपर / नीचे चलते हैं, इसलिए हमें नहीं पता कि आप किस कोड का उल्लेख कर रहे हैं। क्या आप "xyz के उत्तर से कोड का उपयोग" जैसा कुछ कह सकते हैं?
ADTC

4
Btw, साफ जवाब। लेकिन जब थंडर के जवाब की तुलना की जाती है, तो इसे डिफ़ॉल्ट रूप में सेट करने के विपरीत RequestConfigहर में स्थापित करने में क्या अंतर HttpPostहै HttpClient?
ADTC

2
हां, आप सही हैं, उपरोक्त कोड "स्वीकृत उत्तर" को संदर्भित करता है जिसे समय में नहीं बदलना चाहिए। मैं अपने उत्तर को वैसे भी अपडेट करूंगा ..
pmartin8

10

ऐसा लगता है कि आप HttpClient API का उपयोग कर रहे हैं, जिसके बारे में मुझे कुछ नहीं पता है, लेकिन आप कोर जावा के उपयोग से ऐसा कुछ लिख सकते हैं।

try {

   HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
   con.setRequestMethod("HEAD");
   con.setConnectTimeout(5000); //set timeout to 5 seconds
   return (con.getResponseCode() == HttpURLConnection.HTTP_OK);

} catch (java.net.SocketTimeoutException e) {
   return false;
} catch (java.io.IOException e) {
   return false;
}

2
यह अपाचे HTTP क्लाइंट के लिए टाइमआउट को प्रभावित नहीं करेगा।
लाज़

9
यह दावा कभी नहीं किया;)
dbyrne

5
HttpURLConnection की टाइमआउट की धारणा अपर्याप्त है। यदि सर्वर जवाब देना शुरू कर देता है, लेकिन फिर लटक जाता है, तो समय समाप्त नहीं होता है। इस अंतर के कारण Apache का HttpClient एक बेहतर विकल्प है।
benvolioT

7

मैंने पाया कि समय की सेटिंग में सेटिंग करना HttpConnectionParamsऔर HttpConnectionManagerहमारे मामले को हल नहीं करना था। हम org.apache.commons.httpclientसंस्करण 3.0.1 का उपयोग करने तक सीमित हैं ।

मैंने कॉल की java.util.concurrent.ExecutorServiceनिगरानी के लिए एक का उपयोग करके समाप्त कर दिया HttpClient.executeMethod()

यहाँ एक छोटा, आत्म-निहित उदाहरण है

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author Jeff Kirby
 * @since <pre>Jun 17, 2011</pre>
 */
public class Example {

   private static final String SITE = "http://some.website.com/upload";
   private static final int TIME_OUT_SECS = 5;

   // upload a file and return the response as a string
   public String post(File file) throws IOException, InterruptedException {
      final Part[] multiPart = { new FilePart("file", file.getName(), file) };
      final EntityEnclosingMethod post = new PostMethod(SITE);
      post.setRequestEntity(new MultipartRequestEntity(multiPart, post.getParams()));
      final ExecutorService executor = Executors.newSingleThreadExecutor();
      final List<Future<Integer>> futures = executor.invokeAll(Arrays.asList(new KillableHttpClient(post)), TIME_OUT_SECS, TimeUnit.SECONDS);
      executor.shutdown();
      if(futures.get(0).isCancelled()) {
         throw new IOException(SITE + " has timed out. It has taken more than " + TIME_OUT_SECS + " seconds to respond");
      }
      return post.getResponseBodyAsString();
   }

   private static class KillableHttpClient implements Callable<Integer> {

      private final EntityEnclosingMethod post;

      private KillableHttpClient(EntityEnclosingMethod post) {
         this.post = post;
      }

      public Integer call() throws Exception {
         return new HttpClient().executeMethod(post);
      }
   }
}

7

उज़ द्वारा उच्चतम विधि के साथ उक्त विधि को 4.3 संस्करण के बाद से हटा दिया गया है। इसलिए रिक्वेस्ट कॉन्फिग ऑब्जेक्ट को यूजर करना और फिर HTTP क्लाइंट का निर्माण करना बेहतर होगा

    private CloseableHttpClient createHttpClient()
        {
        CloseableHttpClient httpClient;
        CommonHelperFunctions helperFunctions = new CommonHelperFunctions();
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(306);
        cm.setDefaultMaxPerRoute(108);
        RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(15000)
            .setSocketTimeout(15000).build();
        httpClient = HttpClients.custom()
            .setConnectionManager(cm)
            .setDefaultRequestConfig(requestConfig).build();
        return httpClient;
        }

PoolingHttpClientConnectionManager कनेक्शन की अधिकतम डिफ़ॉल्ट संख्या और रूट के अनुसार अधिकतम संख्या सेट करने के लिए उपयोगकर्ता है। मैंने इसे क्रमशः 306 और 108 के रूप में सेट किया है। अधिकांश मामलों के लिए डिफ़ॉल्ट मान पर्याप्त नहीं होंगे।

टाइमआउट सेट करने के लिए: मैंने RequestConfig ऑब्जेक्ट का उपयोग किया है। आप कनेक्शन प्रबंधक से कनेक्शन की प्रतीक्षा करने के लिए टाइमआउट सेट करने के लिए संपत्ति कनेक्शन अनुरोध टाइमआउट भी सेट कर सकते हैं।


5

यह पहले से ही ऊपर benvoliot द्वारा एक टिप्पणी में उल्लेख किया गया था । लेकिन, मुझे लगता है कि यह एक शीर्ष-स्तरीय पद के लायक है क्योंकि इससे मुझे यकीन है कि मुझे अपना सिर खुजलाना पड़ेगा। मैं इसे पोस्ट कर रहा हूँ अगर यह किसी और को बाहर निकालने में मदद करता है।

मैंने एक साधारण टेस्ट क्लाइंट लिखा और CoreConnectionPNames.CONNECTION_TIMEOUTटाइमआउट उस मामले में पूरी तरह से काम करता है। यदि सर्वर प्रतिक्रिया नहीं देता है तो अनुरोध रद्द हो जाता है।

सर्वर कोड के अंदर मैं वास्तव में परीक्षण करने की कोशिश कर रहा था, समान कोड कभी भी बाहर नहीं था।

CoreConnectionPNames.SO_TIMEOUTHTTP कनेक्शन ( CoreConnectionPNames.CONNECTION_TIMEOUT) के बजाय सॉकेट कनेक्शन गतिविधि ( ) पर समय-समय पर इसे बदलना मेरे लिए समस्या तय करता है।

इसके अलावा, अपाचे डॉक्स को ध्यान से पढ़ें: http://hc.apache.org/httpcompenders-core-ga/httpcore/apidocs/org/apache/http/params/CoreConnectionPNames.htmlCCONNECTION_TIMEOUT

नोट जो कहता है उस पर ध्यान दें

कृपया ध्यान दें कि यह पैरामीटर केवल उन कनेक्शनों पर लागू किया जा सकता है जो किसी विशेष स्थानीय पते से जुड़े हैं।

मुझे उम्मीद है कि किसी और को मेरे द्वारा गए सभी सिर को खरोंचने से बचाता है। यह मुझे डॉक्यूमेंटेशन को अच्छी तरह से नहीं पढ़ना सिखाएगा!


2

ऑप ने बाद में कहा कि वे Apache Commons HttpClient 3.0.1 का उपयोग कर रहे थे

 HttpClient client = new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
        client.getHttpConnectionManager().getParams().setSoTimeout(5000);

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.