2012-11-16 22 views
8

मैं एक सर्वर के लिए जावा क्लाइंट स्थापित कर रहा हूं जिसे मैं समय-समय पर मतदान करता हूं और विशेष प्रतिक्रिया के आधार पर संदेश भेजता हूं। कक्षा के लिए उपयोग की जाने वाली रणनीति निम्नानुसार है:अपाचे एचटीपी क्लाइंट सर्वर रणनीति के लिए एकाधिक मतदान कनेक्शन

public class PollingClient { 
    private HttpClient client = getHttpClient(); // I get a DefaultHttpClient this way so it's easier to add connection manager and strategy etc to the client later 
    private HttpPost httpPost = getHttpPost(); // same idea, I set headers there 

    public String poll() { 
     List<NameValuePair> formparams = new ArrayList<NameValuePair>(); 
     formparams.add(new BasicNameValuePair("id", someId)); 

     String responseString = null; 

     try { 
      UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formparams, "UTF-8");   
      httppost.setURI(polluri)); 
      httppost.setEntity(formEntity); 
      HttpResponse response = httpclient.execute(httppost); 
      HttpEntity entity = response.getEntity(); 


      if (entity != null) { 
       responseString = EntityUtils.toString(entity); 
      } 

      EntityUtils.consume(entity); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public void send(String msg) { 
     List<NameValuePair> formparams = new ArrayList<NameValuePair>(); 
     formparams.add(new BasicNameValuePair("msg", msg)); 
     formparams.add(new BasicNameValuePair("id", someId)); 

     String responseString = null; 

     try { 
      UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formparams, "UTF-8"); 

      httppost.setURI(new URI(URL + "send")); 
      httppost.setEntity(formEntity); 

      HttpResponse response = httpclient.execute(httppost); 
      HttpEntity entity = response.getEntity(); 


      if (entity != null) { 
       responseString = EntityUtils.toString(entity); 
      } 

      EntityUtils.consume(entity); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

मैं एक थ्रेड शुरू करता हूं जो लगभग 3 सेकंड में मतदान करता है। मैं मतदान परिणामों के आधार पर मुख्य धागे से संदेश भेज सकता हूं। कोड काम करता है लेकिन मुझे निम्नलिखित दो अपवाद देता रहता है लेकिन बीच में काम करता रहता है।

java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated. 
Make sure to release the connection before allocating another one. 

org.apache.http.NoHttpResponseException: The target server failed to respond. 

मैं अपवादों को म्यूट कर सकता हूं लेकिन मैं जानना चाहता हूं कि क्या हो रहा है। मैं Google के माध्यम से कोई समाधान खोजने में असमर्थ था। मैंने सामग्री का उपभोग करने की कोशिश की है, प्रेषण विधि में एक नई HttpPost ऑब्जेक्ट बनाएं, इस तरह की चीजें लेकिन अब तक कुछ भी मदद नहीं मिली है।

इस तरह की स्थिति के लिए एक अच्छी रणनीति क्या है। मैं वर्तमान में मामले में HttpPost ऑब्जेक्ट में keep-alive शीर्षलेख सेट करता हूं। इसके अलावा मुझे नहीं लगता कि मैं कुछ भी करता हूं। मुझे लगता है कि इसे समग्र रूप से रणनीति के साथ करना है। मैं हर कनेक्शन के लिए नई वस्तु नहीं बनाना चाहता हूं लेकिन मुझे यह भी नहीं पता कि पुन: उपयोग के किस स्तर की सिफारिश की जाती है। किसी भी मदद के लिए धन्यवाद। ओह .. और यह HttpClient 4.2.2

उत्तर

1

@ साद का जवाब बहुत उपयोगी था, लेकिन कई समवर्ती अनुरोधों के साथ परीक्षण एकल यूआरएल लोड करने का प्रयास करते समय मुझे देरी हुई है।

यहां अद्यतन संस्करण है जो समस्या का समाधान करता है।

DefaultHttpClient client = new DefaultHttpClient(); 
    ClientConnectionManager mgr = client.getConnectionManager(); 
    HttpParams params = client.getParams(); 
    int maxConnections = 100; 
    params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(maxConnections)); 
    params.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, maxConnections); 
    ThreadSafeClientConnManager conman = new ThreadSafeClientConnManager(params, mgr.getSchemeRegistry()); 
    client = new DefaultHttpClient(conman, params); 
0

ये विधियां सिंक्रनाइज़ नहीं हैं और आप विभिन्न धागे से कॉल कर रहे हैं। क्या यह संभव है कि आपका कोड भेजने() को कॉल करने का प्रयास कर सकता है जबकि एक मतदान() ऑपरेशन चल रहा है? मुझे लगता है कि अगर आप एक ही ऑब्जेक्ट का उपयोग कर एक ही समय में दो अनुरोध करने का प्रयास करते हैं तो HttpClient इसे पसंद नहीं करेगा।

(इस समस्या है, तो एक छोटी सी ठीक मानते हुए कि आपके सूत्र है कि उन्हें फोन अवरुद्ध कोई आपत्ति नहीं है, दोनों तरीकों से सिंक्रनाइज़ कीवर्ड जोड़ने के लिए किया जाएगा।)

0

यह overkill हो सकता है, लेकिन आप http कनेक्शन हैंडिंग को समर्पित धागा होने पर विचार कर सकते हैं। यह धागा तब तक सोएगा जब तक कि मतदान का समय न हो या भेजने के लिए संकेत दिया जाए। इसका लाभ केवल एक कनेक्शन का उपयोग किया जाता है।

1

मैं नीचे दिए गए कोड का उपयोग कर समाप्त हुआ। यह काम करता है ... कोई विचार नहीं है क्यों।

DefaultHttpClient client = new DefaultHttpClient(); 
ClientConnectionManager mgr = client.getConnectionManager(); 
HttpParams params = client.getParams(); 
client = new DefaultHttpClient(new ThreadSafeClientConnManager(params, mgr.getSchemeRegistry()), params);