2011-11-22 21 views
20

में बड़ी मात्रा में डेटा स्थानांतरित करें मैंने डब्ल्यूसीएफ में एक वेब सेवा बनाई है जो प्रत्येक पंक्ति में 10 डेटा के साथ 54000 से अधिक डेटा-पंक्तियां लौटाती है। मैंने संचार के लिए wsHttp बाइंडिंग का उपयोग किया है। यह सेवा कम डेटा (यानी 2000 पंक्तियों) के साथ अच्छी तरह से काम करती है लेकिन यह 50000+ पंक्तियों (~ 2 एमबी) के साथ बड़े रिकॉर्ड सेट भेजने का प्रयास करते समय बाहर निकलती है। अपवाद संदेश इसडब्ल्यूसीएफ सेवा

http://localhost:9002/MyService.svc पर HTTP प्रतिक्रिया प्राप्त करते समय एक त्रुटि हुई। यह HTTP प्रोटोकॉल का उपयोग न करने वाले सेवा एंडपॉइंट बाध्यकारी के कारण हो सकता है। यह सर्वर द्वारा निरस्त HTTP अनुरोध संदर्भ के कारण भी हो सकता है (संभवतः सेवा बंद होने के कारण)। अधिक जानकारी के लिए सर्वर लॉग देखें।

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

<system.serviceModel> 
    <bindings> 
    <wsHttpBinding> 
     <binding name="MyWsHttpBinding" /> 
    </wsHttpBinding> 
    </bindings> 
    <services> 
    <service name="AdminService"> 
     <endpoint address="AdminSrv" 
       binding="wsHttpBinding" 
       contract="IAdminService"/> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     <host> 
     <baseAddresses> 
      <add baseAddress="/Bus/IRfotoWCF" /> 
     </baseAddresses> 
     </host> 
    </service> 
    </services> 
    <behaviors> 
    <serviceBehaviors> 
     <behavior> 
     <!-- To avoid disclosing metadata information, 
        set the value below to false and remove the metadata endpoint above before deployment --> 
     <serviceMetadata httpGetEnabled="True"/> 
     <!-- To receive exception details in faults for debugging purposes, 
        set the value below to true. Set to false before deployment 
        to avoid disclosing exception information --> 
     <serviceDebug includeExceptionDetailInFaults="True" /> 
     </behavior> 
    </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"></serviceHostingEnvironment> 
</system.serviceModel> 

मेरे क्लाइंट विन्यास

<system.serviceModel> 
    <bindings> 
    <basicHttpBinding> 
     <binding name="BasicHttpBinding_IAdminService" closeTimeout="00:01:00" 
       openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
       allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
       maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
       messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
       useDefaultWebProxy="true"> 
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
     <security mode="None"> 
      <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> 
      <message clientCredentialType="UserName" algorithmSuite="Default" /> 
     </security> 
     </binding> 
    </basicHttpBinding> 
    </bindings> 
    <client> 
    <endpoint address="http://localhost/TestService/AdminService.svc" 
       binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAdminService" 
       contract="IAdminService" name="BasicHttpBinding_IAdminService" /> 
    </client> 
</system.serviceModel> 

के रूप में है किसी को दोनों क्लाइंट और सर्वर साइड में excact विन्यास के साथ मेरी मदद कर सकते हैं सर्वर पर

मेरी सेवा विन्यास है। भले ही मुझे से बाध्यकारी बदलने की आवश्यकता है, wsHttp बाइंडिंग से netTcp बाइंडिंग - मुझे ऐसा करने में कोई समस्या नहीं है। अग्रिम में धन्यवाद।

उत्तर

33

बहुत सारी जांच के बाद मुझे समाधान मिला। असल में कई चीजों को बदलने की जरूरत है।

सर्वर-साइड में किए जाने वाले निम्नलिखित परिवर्तनों की आवश्यकता है।

पहले मैं लंबी अवधि के लिए अनुरोध को चलाने के लिए मेरी httpRuntime तत्व में एक बड़ा मूल्य के लिए एक maxRequestLength स्थापित करने के लिए किया था।

<system.web>  
<httpRuntime maxRequestLength="102400" /> 
</system.web> 

दूसरा मैं 2147483647 की एक बड़ी मूल्य के साथ maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize पर कस्टम परिवर्तन के साथ शुरू की netTcpBinding binnding।

<binding name="myNetTcpBinding" 
maxBufferPoolSize="2147483647" 
maxBufferSize="524288" 
maxReceivedMessageSize="2147483647"> 

तीसराserviceBehaviors और endpointBehaviors bellow की तरह दोनों में maxItemsInObjectGraph जोड़ने (भूल न service और endpoint नोड में व्यवहार नाम का उल्लेख करने के लिए)

<behaviors> 
     <serviceBehaviors>   
     <behavior name="myNetTcpBehaviour"> 
      <serviceMetadata httpGetEnabled="true"/> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="myNetTcpEndPointBehaviour"> 
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 

अंत में अपने सर्वर विन्यास दिखता है इस तरह

<system.web>  
    <httpRuntime maxRequestLength="102400" /> 
</system.web> 


    <system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
     <binding name="MyWsHttpBinding" /> 
     </wsHttpBinding> 
     <netTcpBinding> 
     <binding name="myNetTcpBinding" 
       closeTimeout="00:01:00" 
       openTimeout="00:01:00" 
       receiveTimeout="00:10:00" 
       sendTimeout="00:01:00" 
       transactionFlow="false" 
       transferMode="Buffered" 
       transactionProtocol="OleTransactions" 
       hostNameComparisonMode="StrongWildcard" 
       listenBacklog="10" 
       maxBufferPoolSize="2147483647" 
       maxBufferSize="524288" 
       maxConnections="10" 
       maxReceivedMessageSize="2147483647"> 
      <readerQuotas maxDepth="32" 
         maxStringContentLength="8192" 
         maxArrayLength="16384" 
         maxBytesPerRead="4096" 
         maxNameTableCharCount="16384" /> 
      <reliableSession ordered="true" 
          inactivityTimeout="00:10:00" 
          enabled="false" /> 
      <security mode="Transport"> 
      <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> 
      </security> 
     </binding> 
     </netTcpBinding> 
    </bindings> 
    <services> 
     <service name="AdminService" behaviorConfiguration="myNetTcpBehaviour"> 
     <endpoint address="AdminSrv" 
        binding="netTcpBinding" 
        bindingConfiguration="myNetTcpBinding" 
        contract="IAdminService" 
        behaviorConfiguration="myNetTcpEndPointBehaviour"/> 

     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     <host> 
      <baseAddresses> 
      <add baseAddress="/Bus/IRfotoWCF" /> 
      </baseAddresses> 
     </host> 
     </service> 
    <behaviors> 
     <serviceBehaviors>   
     <behavior name="myNetTcpBehaviour"> 
      <serviceMetadata httpGetEnabled="true"/> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="myNetTcpEndPointBehaviour"> 
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"></serviceHostingEnvironment> 
    </system.serviceModel> 

अब क्लाइंट साइड configuratioin पर आप बदलना maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"

और भी आप अंत बिंदु व्यवहार विन्यास में maxItemsInObjectGraph="2147483647" जोड़ने की जरूरत की जरूरत है। एक बहुत अभी भी -

 <endpointBehaviors> 
      <behavior name="myEndPointBehavior"> 
       <dataContractSerializer maxItemsInObjectGraph="2147483647" /> 
      </behavior> 
     </endpointBehaviors> 

अब मैं 5.30 मिनट जहां क्वेरी 10 सेकंड के लिए मार डाला तो प्रसारण समय 5.20 मिनट है भीतर पंक्तियों संचारित कर सकते हैं।

टिप्पणी करने के लिए स्वतंत्र महसूस करें और सुधार के लिए कोई सुझाव दें।

+0

मुझे समझ में नहीं आता है। क्या यह वास्तव में एक अच्छा समाधान है, जब एक सेवा 5.20 मिनट के दौरान दूसरी सेवा के लिए इंतजार कर रही है। मुझे लगता है कि यहां वास्तुकला के बारे में बड़ा सवाल है, लेकिन मुझे समाधान नहीं मिल रहा है। – Vladislav

+0

मैं बड़े डेटा को स्थानांतरित करने के साथ परीक्षण की गति जारी रखता हूं। "भाग" विधि का उपयोग करके मैं 300 000 (!) पंक्तियां भेज सकता हूं, इसे मेरी सेवा की कॉन्फ़िगरेशन में किसी भी बदलाव के बिना 4.34min के भीतर डेटाबेस में सहेजता है। मैं 50 पंक्तियों के साथ भाग के लिए बस अपना डेटा अलग कर रहा हूँ। – Vladislav

+0

आपको XML के बजाय डेटाकंट्रैक सीरिएलाइज़र का उपयोग करना चाहिए। यह अब तक मैन्युअल संदर्भ.cs के अंदर नौकरी को प्रतिस्थापित करता है। – NickD

1

यदि आप बाध्यकारी विवरण देखते हैं तो वे पूरी तरह सर्वर और क्लाइंट पक्ष से मेल नहीं खाते हैं। maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize के लिए गुण सर्वर पक्ष में भी परिभाषित किए जाने हैं। और फिर आपको मूल्यों को उस आकार के अनुसार रखना होगा जिसे आप देख रहे हैं।

+0

मैंने सर्वर और क्लाइंट साइड दोनों में 2147483647 मूल्यों के साथ इन maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize को आजमाया है। अभी भी एक ही अपवाद। –

+0

मैं आपकी पोस्ट में कॉन्फ़िगरेशन फ़ाइल में सेटिंग्स नहीं देख सका। क्या आप सुनिश्चित हैं कि बाध्यकारी विन्यास ठीक से सेट है? – Kangkan

+0

याप, मैंने सर्वर और क्लाइंट साइड दोनों पर अपने स्थानीय में बाइंडिंग कॉन्फ़िगरेशन में उनको कॉन्फ़िगर किया। लेकिन अब मैंने समस्या हल कर ली है- जवाब देखें। वैसे भी धन्यवाद, कृपया उत्तर पर टिप्पणी करने के लिए स्वतंत्र महसूस करें। –

-3

भारी डेटा के लिए डब्ल्यूसीएफ पर लूप के लिए उपयोग करने के बजाय, उपयोगकर्ता परिभाषित तालिका प्रकार का उपयोग करें (यदि आप एसक्यूएल का उपयोग कर रहे हैं)। यह समय 6 मिनट से 15-20 सेकंड तक कम करेगा।

+0

बस क्या ......? – Gareth

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