2010-10-05 117 views
2

我正在寫一個WCF(net.tcp)文件傳輸服務,它將最終將文件拆分成多個部分,並將所述部分從服務器/服務傳輸到客戶端。目前客戶端和服務器是控制檯應用程序。WCF net.tcp唯一的服務給TargetInvocationException/ServiceModel.CommunicationException

在寫這個服務的時候,我在不同的時候得到了以下例外;

System.ServiceModel.CommunicationException:套接字連接被中止。這可能是由處理您的消息時出錯或遠程主機超出接收超時或基礎網絡資源問題引起的。本地套接字超時爲'01:59:59.4220000'。

實際上,它以未處理的異常開始:System.Reflection.TargetInvocationException:操作過程中發生異常,導致結果無效。檢查異常詳情的InnerException。 --->那麼上面的CommunicationException文本就在這裏。

在典型的微軟時尚中,這個異常消息已經無可救藥,所以我終於向社區發出呼籲,看看我是否可以解決這個問題。此外,如果這很重要,客戶端會異步調用兩個服務的方法(InitGetFilePart()和GetFilePart())。根據我的日誌,第一次調用InitGetFilePartAsync(1,1)會一直處理到最後;這意味着調用了'Completed'處理程序,該處理程序又調用vcClient.GetFilePartAsync(FileXferCargo,1),然後它的處理程序生成一個BackgroundWorker線程(workers [chunkNum]。 RunWorkerAsync(cargoHolder [chunkNum] where chunkNum = 1)which本身就完成了這是正確的關於我得到上面提到的TargetInvocationException

在過去,我已經做了各種調整(遺憾的是,我不記得是什麼)到App.config使這個例外消失,但現在我沒有做任何事情似乎有所作爲,我只是不明白爲什麼這種情況繼續發生。

我已閱讀關於此事的其他建議,包括「你必須趕上客戶端的異常,中止當前代理並創建並打開ne一個。「那麼,我嘗試過,但它並沒有出現我能夠趕上這個例外。

我也讀過它可能是由於通過電線發送太多的數據,但是當我嘗試發送我的小4k測試文件時,我得到相同的異常。在我的調查過程中,我還了解到,我可以多次使用帶有UserState參數的* Async()調用來調用1個WCF服務函數/方法,這正是我正在做的。

當談到WCF時,我會承認它是一個可重複的n00b,但我確信我的配置文件正確設置了我正在嘗試做的事情。

以下是客戶端和服務器app.config文件,服務接口定義以及服務實現類的頂部。

客戶的App.config中:

<system.serviceModel> 

    <bindings> 
     <netTcpBinding> 
      <binding name="MyTcpBinding_IFileXferService" 
        receiveTimeout="02:00:00" 
        sendTimeout="02:00:00" 
        transferMode="Streamed" 
        maxBufferSize="65536" 
        maxReceivedMessageSize="2147483647"> 
       <readerQuotas maxStringContentLength="2147483647" 
           maxArrayLength="2147483647" 
           maxBytesPerRead="65536" /> 
       <security mode="Transport"> 
        <transport clientCredentialType="None"> 
         <extendedProtectionPolicy policyEnforcement="Never" /> 
        </transport> 
       </security> 
      </binding> 
     </netTcpBinding> 
    </bindings> 

    <behaviors> 
     <endpointBehaviors> 
      <behavior name="ClientConfigBehavior"> 
       <dataContractSerializer maxItemsInObjectGraph="2147483647" /> 

       <clientCredentials> 
        <serviceCertificate> 
         <authentication certificateValidationMode="None" /> 
        </serviceCertificate> 
       </clientCredentials> 

      </behavior> 
     </endpointBehaviors> 
    </behaviors> 

    <client> 
     <endpoint name="ClientConfig" 
        behaviorConfiguration="ClientConfigBehavior" 
        binding="netTcpBinding" 
        bindingConfiguration="MyTcpBinding_IFileXferService" 
        contract="ServiceRefs.IFileXferService" /> 
    </client> 

</system.serviceModel> 

服務器的應用程序。配置:

<bindings> 
     <netTcpBinding> 
      <!-- Under <netTcpBinding> setting the listenBacklog, 
       maxConnections, and maxBuffer* values high --> 
      <binding name="MyTcpBinding_IFileXferService" 
       receiveTimeout="02:00:00" 
       sendTimeout="02:00:00" 
       openTimeout="00:01:00" 
       transferMode="Streamed" 
       portSharingEnabled="true" 
       listenBacklog="32" 
       maxConnections="64" 
       maxBufferSize="65536" 
       maxReceivedMessageSize="2147483646"> 
       <security mode="Transport"> 
        <transport clientCredentialType="None" /> 
       </security> 
      </binding> 
     </netTcpBinding> 

    </bindings> 

    <services> 
     <service name="MediaServer.LNMediaServerSvc" 
       behaviorConfiguration="ServerConfigBehavior"> 
      <host> 
       <baseAddresses> 
        <add baseAddress="net.tcp://lngsead148191a:9000/fileXferSvc"/> 
       </baseAddresses> 
      </host> 
      <endpoint name="mainEndPoint" 
         binding="netTcpBinding" 
         bindingConfiguration="MyTcpBinding_IFileXferService" 
         contract="ServiceInterfaces.IFileXferService" /> 
     </service> 
    </services> 

    <behaviors> 
     <serviceBehaviors> 
      <behavior name="ServerConfigBehavior"> 
       <serviceDebug includeExceptionDetailInFaults="true"/> 
       <serviceThrottling maxConcurrentCalls="64" /> 
       <dataContractSerializer maxItemsInObjectGraph="2147483646" /> 
       <serviceCredentials> 
        <serviceCertificate findValue="tp_value" 
             x509FindType="FindByThumbprint" /> 
       </serviceCredentials> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 

</system.serviceModel> 

服務接口定義如下;

[DataContract(IsReference = true)] 
public class FileData 
{ 
    private long m_startPos; 

    [DataMember] 
    public long StartPosition 
    { 
     get { return m_startPos; } 
     set { m_startPos = value; } 
    } 

    private long m_endPos; 

    [DataMember] 
    public long EndPosition 
    { 
     get { return m_endPos; } 
     set { m_endPos = value; } 
    } 

    private byte m_chunkNumber; 

    [DataMember] 
    public byte ChunkNumber 
    { 
     get { return m_chunkNumber; } 
     set { m_chunkNumber = value; } 
    } 

    private long m_chunkSize; 

    [DataMember] 
    public long ChunkSize 
    { 
     get { return m_chunkSize; } 
     set { m_chunkSize = value; } 
    } 

    private string md5Hash; 

    [DataMember] 
    public string MD5Hash 
    { 
     get { return md5Hash; } 
     set { md5Hash = value; } 
    } 

    private string m_destFileSpec; 

    [DataMember] 
    public string DestinationFileSpec 
    { 
     get { return m_destFileSpec; } 
     set { m_destFileSpec = value; } 
    } 

    private string m_srcFileSpec; 

    [DataMember] 
    public string SourceFileSpec 
    { 
     get { return m_srcFileSpec; } 
     set { m_srcFileSpec = value; } 
    } 

    private Stream m_sourceStream; 

    [DataMember] 
    public Stream SourceStream 
    { 
     get { return m_sourceStream; } 
     set { m_sourceStream = value; } 
    } 

    private UInt32 m_JobNo; 

    [DataMember] 
    public UInt32 JobNumber 
    { 
     get { return m_JobNo; } 
     set { m_JobNo = value; } 
    } 

    private UInt32 m_fileNumber; 

    [DataMember] 
    public UInt32 FileNumber 
    { 
     get { return m_fileNumber; } 
     set { m_fileNumber = value; } 
    } 

    private long m_fileSize; 

    [DataMember] 
    public long FileSize 
    { 
     get { return m_fileSize; } 
     set { m_fileSize = value; } 
    } 
} 


[DataContract] 
public partial class FileXferCargo 
{ 
    private FileData m_fileData; 

    [DataMember] 
    public FileData FileData 
    { 
     get { return m_fileData; } 
     set { m_fileData = value; } 
    } 


    private bool m_cancelled; 

    [DataMember] 
    public bool Cancelled 
    { 
     get { return m_cancelled; } 
     set { m_cancelled = value; } 
    } 

    private long m_errorCode; 

    [DataMember] 
    public long ErrorCode 
    { 
     get { return m_errorCode; } 
     set { m_errorCode = value; } 
    } 

    private Exception m_exceptionObj; 

    [DataMember] 
    public Exception Exception 
    { 
     get { return m_exceptionObj; } 
     set { m_exceptionObj = value; } 
    } 
} 


[ServiceContract] 
public interface IFileXferService 
{ 
    [OperationContract] 
    bool InitFileRequest(ref FileXferCargo fileRequest); 

    [OperationContract] 
    bool InitGetFilePart(ref FileXferCargo fileCargo); 

    [OperationContract] 
    Stream GetFilePart(FileXferCargo fileCargo); 

    [OperationContract] 
    int CloseFile(FileData fileData); 
} 

Service實現類定義如下;

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
    ConcurrencyMode = ConcurrencyMode.Multiple, 
    UseSynchronizationContext = false) 
] 
public class LNMediaServerSvc : IFileXferService 
{ 
    ... 
} 
+0

打開服務和客戶端上的WCF跟蹤:http://msdn.microsoft.com/en-us/library/ms733025.aspx – 2010-10-05 19:53:21

+1

如果基於HTTP的託管問題將被清除--FileData包含Stream。在Net.Tcp中,我不確定這是否被允許。 – 2010-10-05 19:55:33

+0

該流成員僅在本地用於在多個方法之間傳送流。我前一段時間發現,我無法以這種方式返回流,因此2個Init方法,然後是GetFilePart,它是返回實際Stream的那個。 – 2010-10-05 20:22:58

回答

0

沒有評論按鈕了,所以我會把它放在這裏。是的,我打開了跟蹤,但似乎我需要閱讀一本書來了解跟蹤數據試圖告訴我的所有內容。也就是說,我查看了跟蹤信息,而我看不到的是導致插槽被中止的任何事情。似乎沒有理由發生。 :(

3

爲了您NetTcpBinding的,設置安全模式無法比擬的,在客戶端和服務器的配置文件上都:

<security mode="None" /> 

這是一個快速解決

如果你需要有保障。啓用NetTcpBinding的,那麼你必須執行授權和模擬

在這裏閱讀更多:http://msdn.microsoft.com/en-us/library/ms730088.aspx

從我閱讀和搜索的內容來看,這是一個多跳模仿的問題。模仿只能轉到一跳。通過將安全模式設置爲none,您可以在調用WCF服務時防止身份驗證步驟。

0

對我來說,這是因爲在託管WCF的服務器的web.config中沒有net.tcp綁定。當我爲服務添加相同的綁定時,我沒有得到異常。因此,如果Web和WCF託管在不同的服務器中,則需要在Web和WCF中進行綁定。