Fttler

2011-06-30 8 views
6

की तरह व्यवहार करने के लिए सी # एप्लिकेशन कैसे बनाएं मेरे पास एक कंसोल ऐप है जो रिमोट वेब सर्वर से कनेक्ट करने के लिए 20 या तो थ्रेड का उपयोग करता है और मनमाने ढंग से http अनुरोधों को छोटे आकार में भेजता है, एसएसएल पर 100%। रिमोट वेब सर्वर वास्तव में एक उच्च लोड संतुलित डेटा सेंटर है जो उच्च उपलब्धता प्रणाली से भरा है जो प्रति सेकंड सैकड़ों हजारों अनुरोधों को संभाल सकता है। यह एक सर्वर या बैंडविड्थ मुद्दा नहीं है। ऐसा कहा जा रहा है कि, मैं इसे नहीं चलाता, न ही मुझे इसका कोई प्रभाव पड़ता है कि यह कैसे कॉन्फ़िगर किया गया है, इसलिए यदि मैं चाहता हूं तो भी मैं सर्वर पक्ष में परिवर्तन नहीं कर सका।Fttler

फिडलर के साथ ऐप चलाने पर ऐप आश्चर्यजनक तेज़ प्रदर्शन करता है। जब फिडलर में नहीं चल रहा है तो यह वास्तव में बहुत धीमी है, काम के लिए बेकार होने के बिंदु पर। यह प्रक्रिया के शुरुआती दिनों में कुछ बिंदु पर लॉक लग रहा है, लेकिन यह केवल एक डेडलॉक मुद्दा हो सकता है, मुझे अभी तक यकीन नहीं है।

किसी भी तरह, फिडलर प्रॉक्सी होने के नाते, निस्संदेह मेरे अनुरोध/कनेक्शन को किसी भी तरीके से संशोधित कर रहा है जो अद्भुत थ्रूपुट सुनिश्चित करता है, हालांकि मुझे नहीं पता कि यह क्या कर रहा है। मैं इसे समझने की कोशिश कर रहा हूं ताकि मैं अपने .net एप्लिकेशन को फिडलर कनेक्शन हैंडलिंग व्यवहार की नकल करने के लिए मजबूर कर सकूं, वास्तव में इसे फिडलर

के माध्यम से चलाने के लिए मैंने नीचे कनेक्शन कोड चिपकाया है।

 using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Net; 
    using System.IO; 

    namespace Redacted 
    { 
     public class HiveCommunicator 
     { 

      public static IResponse SendRequest(IRequest request) { 

       ServicePointManager.DefaultConnectionLimit = 60; 
       ServicePointManager.Expect100Continue = false; 


       string hostUrlString = string.Empty; 
       if (request.SiteID <= 0) 
       hostUrlString = string.Format("{0}://{1}{2}", request.UseSSL ? "https" : "http", DataCenters.GetCenter(request.DataCenter), request.Path); 
       else 
       hostUrlString = string.Format("{0}://{1}{2}", request.UseSSL ? "https" : "http", DataCenters.GetCenter(request.DataCenter), string.Format(request.Path, request.SiteID)); 

       HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(hostUrlString); 

       switch (request.ContentType) 
       { 
       default: 
       case ContentTypes.XML: 
        webRequest.ContentType = "application/xml"; 
        break; 
       case ContentTypes.JSON: 
        webRequest.ContentType = "application/json"; 
        break; 
       case ContentTypes.BINARY: 
        webRequest.ContentType = "application/octet-stream"; 
        break; 
       } 

       if (request.RequiresAuthorizationToken) 
       { 
       AuthorizationToken tok = HiveAuthentication.GetToken(request.SiteID); 
       if (tok == null) 
       { 
        return null; 
       } 
       webRequest.Headers.Add(HttpRequestHeader.Authorization, tok.Token); 
       } 

       bool UsesRequestBody = true; 

       switch (request.HttpVerb) 
       { 
       case HttpVerbs.POST: 
        webRequest.Method = "POST"; 
        break; 
       case HttpVerbs.DELETE: 
        webRequest.Method = "DELETE"; 
        UsesRequestBody = false; 
        break; 
       case HttpVerbs.PUT: 
        webRequest.Method = "PUT"; 
        break; 
       default: 
       case HttpVerbs.GET: 
        webRequest.Method = "GET"; 
        UsesRequestBody = false; 
        break; 
       } 

       HttpWebResponse webResponse = null; 
       Stream webRequestStream = null; 

       byte[] webRequestBytes = null; 
       if (UsesRequestBody) 
       { 
       webRequestBytes = request.RequestBytes; 
       webRequest.ContentLength = webRequestBytes.Length; 
       webRequestStream = webRequest.GetRequestStream(); 
       for (int i = 0; i < webRequest.ContentLength; i++) 
       { 
        webRequestStream.WriteByte(webRequestBytes[i]); 
       } 
       } 

       try 
       { 
       webResponse = (HttpWebResponse)webRequest.GetResponse(); 
       } 
       catch (WebException ex) 
       { 

       webResponse = (HttpWebResponse)ex.Response; 
       } 

       if (UsesRequestBody) 
       { 
       webRequestStream.Close(); 
       webRequestStream.Dispose(); 
       } 

       IResponse respReturn = request.ParseResponse(webResponse); 
       webResponse.Close(); 

       return respReturn; 
      } 
     } 
    } 

उत्तर

5

मैं यहां लोगों का धन्यवाद करता हूं जिन्होंने मदद करने की कोशिश की। दुर्भाग्य से इसे माइक्रोसॉफ्ट प्रोफेशनल सपोर्ट के लिए एक कॉल की आवश्यकता थी।

भले ही मैं ServicePointManager.Expect100Continue = false; का उपयोग कर रहा था, यह ऐप जीवन चक्र में देर से हो रहा था। System.Net.Trace लॉग को देखते हुए हमने देखा कि उम्मीद-100 जारी हैडर अभी भी उपयोग किया जा रहा था (फिडलर का उपयोग करते समय)। समाधान यह ऐप स्टार्टअप (मुख्य() में

मैं अनुरोध स्ट्रीम को बंद करने से पहले प्रतिक्रिया स्ट्रीम को पढ़ने का प्रयास कर रहा था।

इसे ठीक करने के बाद, सबकुछ अच्छी तरह से बढ़ गया। ऐप फिडलर के बिना बहुत तेजी से चलता है, जो मैं उम्मीद करता हूं।

कुछ लोगों ने HttpWebResponse पर निपटान करने के लिए कहा। उस वर्ग में सार्वजनिक निपटान विधि नहीं है। मैं मान रहा हूँ। बंद() कॉल। हालांकि() आंतरिक रूप से।

+1

मैंने इस हेडर के साथ भी समस्याओं में भाग लिया है। मैं समझ नहीं पा रहा हूं कि एमएस ने इसे बदलने में इतना मुश्किल क्यों बनाया है। –

1

यहाँ एक जंगली अनुमान ले रहा है, लेकिन यह एक सरल app.config सेटिंग के साथ क्या करना है हो सकता है:

<system.net> 
    <connectionManagement> 
    <add address="*" maxconnection="40"/> 
    </connectionManagement> 
</system.net> 

मैं एक बार एप्लिकेशन का अनुरोध एक बहु लड़ी HTTP में एक ही समस्या थी और यह हल इस समस्या।

+0

टिप के लिए धन्यवाद, मैंने पहले ही कोशिश की थी और यह काम नहीं कर रहा था, लेकिन सुझाव के लिए धन्यवाद;) – Erick

+0

धन्यवाद मिकाएल। इससे मेरा काम बनता है! – carck3r

2

फिडलर के शक्तिशाली कनेक्शन के कारण क्लाइंट कनेक्शन का पुन: उपयोग करने का कारण यह देखने के लिए आप फिडलर के "कनेक्शन विकल्प" के साथ खेल सकते हैं। यदि ऐसा है, तो आप एक साझा सुरक्षित http कनेक्शन पूल को लागू करने पर विचार करना चाहेंगे या बस एक मूवी या कुछ देखें। ^^

+0

इम नहीं बिल्कुल यकीन है कि जहां एक "साझा कनेक्शन पूल सुरक्षित http" की स्थापना के बारे में जानकारी के लिए जाने के लिए मैं अगर आप कुछ गूगल खोज शब्दों का सुझाव सकता है सोच रहा हूँ – Erick

+2

(http://stackoverflow.com/questions/4933450/can-i -reuse-httpwebrequest-बिना-डिस्कनेक्ट करने-से-सर्वर) जॉन स्कीट WebResponse पर स्पष्ट रूप से निपटाने कॉल करने के लिए इतना है कि अंतर्निहित बुनियादी ढांचे में एक ही कनेक्शन का पुन: उपयोग कर सकते हैं का सुझाव दिया। शायद वह मदद करेगा। –

+0

बिंगो। जॉन का जवाब लगभग निश्चित रूप से सही है। – EricLaw

0

यह देखते हुए कि आपका एप्लिकेशन "मनमाना http अनुरोधों को आकार में छोटा" भेजता है, यह को Nagle एल्गोरिदम अक्षम करने में मदद कर सकता है।

ServicePointManager.UseNagleAlgorithm = true; 

MSDN से: तत्वों का एक नंबर प्रदर्शन जब HttpWebRequest का उपयोग कर, सहित प्रभावित कर सकता है:

Nagle एल्गोरिथ्म [...] छोटे संदेशों के दृश्यों बड़ा टीसीपी पैकेट में डेटा नेटवर्क पर भेजे जाने से पहले जम जाता है। [...] निरंतर उच्च मात्रा प्रवाह के लिए आम तौर पर, एक प्रदर्शन में सुधार Nagle एल्गोरिथ्म का उपयोग कर महसूस किया है। लेकिन छोटे थ्रूपुट अनुप्रयोगों के लिए, प्रदर्शन में गिरावट देखी जा सकती है। [...] यदि कोई अनुप्रयोग कम विलंबता कनेक्शन का उपयोग है, यह गलत को यह गुण सेट करने में मदद कर सकते हैं।