2011-11-22 36 views
20

Tôi đã tạo một dịch vụ web trong WCF trả về hơn 54000 hàng dữ liệu với 10 dữ liệu trong mỗi hàng. Tôi đã sử dụng số điện thoại wsHttpBinding để liên lạc. Dịch vụ này hoạt động tốt với ít dữ liệu hơn (tức là 2000 hàng) nhưng nó bị loại bỏ khi cố gửi một bộ hồ sơ lớn với hơn 50000 hàng (~ 2MB). Thông báo ngoại lệ là như thế nàyChuyển số lượng lớn dữ liệu trong dịch vụ WCF

Đã xảy ra lỗi khi nhận phản hồi HTTP tới http://localhost:9002/MyService.svc. Điều này có thể là do ràng buộc điểm cuối dịch vụ không sử dụng giao thức HTTP. Điều này cũng có thể là do bối cảnh yêu cầu HTTP bị máy chủ hủy bỏ (có thể do việc tắt dịch vụ). Xem nhật ký máy chủ để biết thêm chi tiết.

Xin vui lòng không cho tôi biết sử dụng phân trang ở phía khách hàng - Tôi biết rằng nó sẽ giải quyết được vấn đề. Nhưng tôi cần toàn bộ đoạn dữ liệu trong phần cuối của máy khách.

cấu hình dịch vụ của tôi trên máy chủ là như

<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> 

cấu hình Khách hàng của tôi là như

<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> 

một ai đó sẽ giúp tôi ra với cấu hình excact cả client và server side. Ngay cả khi tôi cần thay đổi ràng buộc từ wsHttpBinding đến netTcpBinding - tôi không gặp vấn đề gì khi thực hiện điều đó. Cảm ơn trước.

Trả lời

33

Sau nhiều lần điều tra, tôi đã nhận được giải pháp. Trên thực tế một số điều cần phải được thay đổi.

Các thay đổi sau cần được thực hiện trong Phía máy chủ.

Đầu tiên tôi phải thiết lập một maxRequestLength đến một giá trị lớn hơn trong phần tử httpRuntime của tôi để chạy theo yêu cầu cho thời gian dài hơn.

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

Second tôi giới thiệu netTcpBinding binnding với những thay đổi tùy chỉnh trên maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize với một giá trị lớn 2147483647.

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

Thứ ba thêm maxItemsInObjectGraph trong cả hai serviceBehaviorsendpointBehaviors như dưới đây (không quên đề cập đến tên hành vi trong nút serviceendpoint)

<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> 

Cuối cùng vẻ cấu hình máy chủ của tôi như thế này

<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> 

Bây giờ trên client-side configuratioin bạn cần phải thay đổi maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"

cũng bạn cần phải thêm maxItemsInObjectGraph="2147483647" trong cấu hình hành vi đầu cuối.

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

Bây giờ tôi có thể truyền hàng trong 5,30 phút hợp truy vấn được thực hiện trong 10 giây nên thời gian truyền là 5.20 phút - vẫn còn rất nhiều.

Hãy bình luận và đề xuất cải thiện.

+0

Tôi không hiểu. Nó là một giải pháp thực sự tốt, khi một dịch vụ chờ đợi một dịch vụ khác trong 5,20 phút. Tôi nghĩ đây là câu hỏi lớn về kiến ​​trúc, nhưng tôi không thể tìm ra giải pháp. – Vladislav

+0

Tôi tiếp tục thử nghiệm với tốc độ truyền dữ liệu lớn. Sử dụng "Chunks" phương pháp tôi có thể gửi 300 000 (!) Hàng, lưu nó vào cơ sở dữ liệu trong vòng 4,34 phút mà không có bất kỳ thay đổi trong cấu hình dịch vụ của tôi. Tôi chỉ tách dữ liệu của tôi cho các khối với 50 hàng. – Vladislav

+0

Bạn nên sử dụng Trình mã hóa dữ liệu nối tiếp thay vì XML. Điều này cho đến nay một công việc thay thế thủ công bên trong reference.cs. – NickD

1

Nếu bạn xem chi tiết ràng buộc, chúng không khớp hoàn toàn trên máy chủ và phía máy khách. Các thuộc tính cho maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize cũng phải được xác định ở phía máy chủ. Và sau đó bạn cần phải đặt các giá trị theo kích thước bạn đang xem xét.

+0

Tôi đã thử các maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize với các giá trị 2147483647 cả ở phía máy chủ và máy khách. Vẫn là ngoại lệ tương tự. –

+0

Tôi không thể thấy cài đặt trong tệp cấu hình trong bài đăng của bạn. Bạn có chắc chắn rằng cấu hình ràng buộc được đặt đúng không? – Kangkan

+0

Yap, tôi đã cấu hình các cấu hình này trong cấu hình liên kết ở cả máy chủ và phía máy khách của tôi. Nhưng bây giờ tôi đã giải quyết được vấn đề - xem câu trả lời. Cảm ơn anyway, plz cảm thấy tự do để bình luận về câu trả lời. –

-3

Thay vì sử dụng vòng lặp qua WCF cho dữ liệu cồng kềnh, hãy sử dụng loại bảng do người dùng xác định (nếu bạn đang sử dụng SQL). Nó sẽ giảm thời gian từ 6 phút xuống còn 15-20 giây.

+0

Chỉ là những gì ......? – Gareth

Các vấn đề liên quan