2017-09-27 28 views
9

फेंकता है हमारे पास एक डब्ल्यूसीएफ सेवा है जो क्लाइंट से क्लाइंट स्वीकार करता है (क्लाइंट सर्वर पर फ़ाइल अपलोड कर रहा है)। हालांकि, यदि सर्वर स्ट्रीम के पहले या उसके दौरान एक FaultException फेंकता है तो क्लाइंट केवल अंत तक स्ट्रीमिंग पर चलता है, जिस पर यह सर्वर से FaultException प्राप्त करता है - क्लाइंट के लिए समय & बैंडविड्थ बर्बाद कर रहा है।डब्ल्यूसीएफ - सर्वर से सर्वर से सर्वर को रोक दें यदि सर्वर FaultException

इसी प्रकार के प्रश्न:

How to Abort a WCF File Upload from the Server-Side Method

निम्नलिखित (सरलीकृत WCF सेवा) ले लो

Namespace JP_WCF 
    <ServiceContract> _ 
    Public Interface IJP_WCF 
     <OperationContract> _ 
     <FaultContract(GetType(JP_WCF_Fault))> _ 
     Sub UploadFile(request As JP_WCF_FileUpload) 

     <OperationContract> _ 
     <FaultContract(GetType(JP_WCF_Fault))> _ 
     Function fakeError(ByVal int1 As Integer, ByVal int2 As Integer) As Integer 

     <OperationContract> _ 
     <FaultContract(GetType(JP_WCF_Fault))> _ 
     Function Ping() As Date 
    End Interface 

    <MessageContract> _ 
    Public Class JP_WCF_FileUpload 
     Implements IDisposable 

     <MessageHeader(MustUnderstand:=True)> _ 
     Public FileName As String 

     <MessageHeader(MustUnderstand:=True)> _ 
     Public Length As Long 

     <MessageBodyMember(Order:=1)> _ 
     Public FileByteStream As System.IO.Stream 

     Public Sub Dispose() Implements IDisposable.Dispose 
      If FileByteStream IsNot Nothing Then 
       FileByteStream.Close() 
       FileByteStream = Nothing 
      End If 
     End Sub 
    End Class 

    <DataContract> _ 
    Public Class JP_WCF_Fault 
     <DataMember> _ 
     Public Property EventID() As Integer 
     <DataMember> _ 
     Public Property Message() As String 
     <DataMember> _ 
     Public Property Description() As String 

     Public Sub New(ByVal _EventID As Integer, ByVal _Message As String, ByVal _Description As String) 
      Me.EventID = _EventID 
      Me.Message = _Message 
      Me.Description = _Description 
     End Sub 
    End Class 

End Namespace 

उदाहरण सर्वर विधि:

Try 
    Dim sourceStream As Stream = request.FileByteStream 
    Dim uploadFolder As String = "C:\upload\" 
    Dim filePath As String = Path.Combine(uploadFolder, request.FileName) 

    Using targetStream = New FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None) 
     sourceStream.CopyTo(targetStream) 
     targetStream.Close() 
     sourceStream.Close() 
    End Using 
Catch ex As Exception 
    Throw New FaultException(Of JP_WCF_Fault)(New JP_WCF_Fault(8, ex.Message, ex.ToString), ex.Message) 
End Try 

उदाहरण क्लाइंट विधि:

Dim fileInfo As New System.IO.FileInfo(filePath) 
Dim startTime As DateTime = DateTime.Now 
Console.WriteLine("Starting V2 upload: " + DateTime.Now.ToString()) 

Dim JPCS As New JP_WCFService.JP_WCFClient() 

Using stream As New System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read) 
    Using uploadStreamWithProgress As New JP_StreamWithProgress(stream) 
     AddHandler uploadStreamWithProgress.ProgressChanged, AddressOf uploadStreamWithProgress_ProgressChanged 
     Try 
      JPCS.UploadFile(fileInfo.Name, fileInfo.Length, uploadStreamWithProgress) 
     Catch ex As FaultException(Of JP_WCFService.JP_WCF_Fault) 
      Console.WriteLine("Upload Error: " & ex.Detail.Message & " (EventID: " & ex.Detail.EventID.ToString & ")") 
     End Try 
    End Using 
End Using 
Dim endTime As DateTime = DateTime.Now 
Dim durationInMS As Double = (endTime - startTime).TotalMilliseconds 
Console.WriteLine(vbCr & "V2 Upload Completed: " + DateTime.Now.ToString() + " (" + durationInMS.ToString() + ")") 
JPCS.Close() 

web.config

<system.serviceModel> 
    <bindings> 
     <customBinding> 
      <binding name="JP_WCFBinding"> 
       <!-- maxReceivedMessageSize 600MB, maxBufferSize 2MB --> 
       <binaryMessageEncoding compressionFormat="GZip" /> 
       <httpsTransport transferMode="Streamed" maxReceivedMessageSize="629145600" maxBufferSize="2097152"/> 
      </binding> 
     </customBinding> 
    </bindings> 
    <services> 
     <service behaviorConfiguration="JP_WCFbehavior" name="JP_WCF.JP_WCFServices"> 
      <endpoint address="" binding="customBinding" bindingConfiguration="JP_WCFBinding" contract="JP_WCF.IJP_WCF"/> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="JP_WCFbehavior"> 
       <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" /> 
       <serviceDebug includeExceptionDetailInFaults="true" /> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
</system.serviceModel> 

app.config

<system.serviceModel> 
    <bindings> 
     <customBinding> 
      <binding name="CustomBinding_IJP_WCF"> 
       <binaryMessageEncoding compressionFormat="GZip" /> 
       <httpsTransport transferMode="Streamed" /> 
      </binding> 
     </customBinding> 
    </bindings> 
    <client> 
     <endpoint address="https://dev-wcf.localhost/JP_WCF.svc" 
      binding="customBinding" bindingConfiguration="CustomBinding_IJP_WCF" 
      contract="JP_WCFService.IJP_WCF" name="CustomBinding_IJP_WCF" /> 
    </client> 
</system.serviceModel> 
+0

मैं सोच रहा हूँ, आप कैसे पता लगा था कि एक अपवाद हुई के बाद स्ट्रीम करने के लिए जारी है? –

+0

इसके अलावा, 'अपलोडस्ट्रीम विथ प्रोग्रेस' के लिए कार्यान्वयन क्या है? –

उत्तर

2

क्या आपके ग्राहकों के पास डुप्लेक्स चैनल है? यदि ऐसा है, तो फ़ाइल अपलोड होने के बाद जानकारी भेजने के लिए क्लाइंट अनुबंध पर कॉलबैक के लिए यह काफी आगे है।

यदि नहीं, तो यहां एक अच्छा दृष्टिकोण मेमोरी बफर का उपयोग कर सर्वर में अपने डेटा को स्ट्रीम करने के लिए होगा। नीचे दिए गए कुछ अच्छे उदाहरण हैं।

यह बात यह है कि आप फ़ाइल को क्लाइंट पर भाग में विभाजित करते हैं और इसे सर्वर पर खंड-दर-खंड भेजते हैं। यदि कोई खंड विफल हो जाता है, तो यह या तो उस खंड को पुनः प्रयास कर सकता है, या बिना किसी डेटा को भेजे बिना शानदार विफल हो सकता है।

ये संदर्भ क्लाइंट पर इस तर्क को संभालने के लिए StreamWithProgress कक्षा का उपयोग करते हैं। उम्मीद है की यह मदद करेगा।

Code Project reference

Simple implementation using StreamWithProgress class

3

आप इस कॉल के प्रदर्शन के बारे में चिंतित हैं, तो आप हमेशा एक सर्वर कॉल इस की वैधता की जांच करने के लिए कर सकता है स्ट्रीमिंग से पहले अपलोड करें। इस तरह यदि कोई समस्या हो और आप अपने आवेदन (किसी भी महंगी) में किसी अपवाद स्थिति से बचने के लिए फ़ाइल को स्ट्रीम करने से बच सकते हैं।

तो आप उस स्थान

  • फ़ाइल का आकार जा रहा है वैध
  • किसी भी करने के लिए लिखने के लिए सर्वर की तरह

    1. मान्य फ़ाइल स्थान
    2. अनुमति चीजों को मान्य करने के लिए अपेक्षाकृत जल्दी यात्रा बनाना होगा प्रासंगिक व्यापार नियम

    फिर आप आवेदन प्रवाह को प्रबंधित करने के बिना अपना कॉल कर सकते हैं अपवादों का उपयोग करना। याद रखें: असाधारण परिस्थितियों के लिए अपवाद होना चाहिए। इस तरह यदि आपका आवेदन अपवाद बढ़ाता है, तो इसका मतलब है कि कुछ असामान्य हो गया है और गति में डुबकी अधिक आकर्षक है (क्योंकि यह मामला सैद्धांतिक रूप से बहुत दुर्लभ होगा)।

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