WCF net.tcp только служба, предоставляющая TargetInvocationException / ServiceModel.CommunicationException - PullRequest
2 голосов
/ 05 октября 2010

Я пишу службу передачи файлов WCF (net.tcp), которая в конечном итоге разбивает файлы на несколько частей и передает эти части клиенту с сервера / службы. В настоящее время клиент и сервер являются консольными приложениями.

При написании этой услуги я в разное время получал следующее исключение:

System.ServiceModel.CommunicationException: соединение с сокетом было прервано. Это может быть вызвано ошибкой обработки вашего сообщения или превышением тайм-аута приема удаленным хостом, или проблемой основного сетевого ресурса. Тайм-аут локального сокета был «01: 59: 59.4220000».

На самом деле, оно начинается как необработанное исключение: System.Reflection.TargetInvocationException: во время операции произошло исключение, делающее результат недействительным. Проверьте InnerException для подробностей исключения. ---> тогда приведенный выше текст CommunicationException прямо здесь.

В типичной манере Microsoft это сообщение об исключении выходит за рамки бесполезного, поэтому я, наконец, призываю сообщество посмотреть, могу ли я решить эту проблему.

Кроме того, в случае, если это важно, клиент вызывает асинхронно два метода службы (InitGetFilePart () и GetFilePart ()). Согласно моим журналам, первый вызов InitGetFilePartAsync (1, 1) обрабатывается до конца; это означает, что вызывается его обработчик 'Completed', который, в свою очередь, вызывает vcClient.GetFilePartAsync (FileXferCargo, 1), а затем его обработчик порождает поток BackgroundWorker (worker [chunkNum]. RunWorkerAsync (cargoHolder [chunkNum] где chunkNum = 1), который сам завершает работу. Это верно в тот момент, когда я получаю исключение TargetInvocationException, указанное выше.

В прошлом я делал различные изменения (к сожалению, я не могу вспомнить, что именно) в App.config, чтобы исключить это исключение, но теперь ничто из того, что я делаю, кажется, не имеет никакого значения, и я просто НЕ понимаю почему это происходит.

Я прочитал другой совет по этому вопросу, в том числе: «Вы должны отловить исключение на клиенте, прервать текущий прокси-сервер и создать и открыть новый». Я пытался это сделать, но, похоже, мне не удалось поймать это исключение.

Я также читал, что это может быть связано с отправкой слишком большого количества данных по проводной связи, но когда я пытаюсь отправить свой маленький тестовый файл 4k, я получаю то же исключение. Во время моих исследований я также прочитал, что могу вызвать 1 сервисную функцию / метод WCF, много раз используя вызовы * Async () с параметром UserState, что я и делаю.

Я признаю, что являюсь надежным n00b, когда дело доходит до WCF, но я уверен, что мои конфигурационные файлы установлены правильно для того, что я пытаюсь сделать.

Здесь перечислены файлы 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>

App.config сервера:

    <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);
}

Класс реализации Сервиса определяется следующим образом:

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

Ответы [ 3 ]

3 голосов
/ 01 марта 2011

Для вашего netTcpBinding установите режим безопасности равным none для файлов конфигурации клиента и сервера:

<security mode="None" />

Это быстрое решение.

Если вам нужно включить защиту для netTcpBinding, вам нужно реализовать делегирование и олицетворение.

подробнее здесь: http://msdn.microsoft.com/en-us/library/ms730088.aspx

Из того, что я прочитал и гуглилэто проблема многократного подражания.Олицетворение может переноситься только на один прыжок.Установив для режима безопасности значение none, вы предотвращаете шаг аутентификации при вызове службы WCF.

0 голосов
/ 17 июля 2013

Для меня это было из-за отсутствия привязки net.tcp в web.config на сервере, где размещался WCF. Когда я добавил такую ​​же привязку для сервиса, я не получил исключения. Поэтому вам необходимо иметь привязку с обеих сторон в Web и WCF, если они размещены на разных серверах.

0 голосов
/ 06 октября 2010

У меня больше нет кнопки комментариев, поэтому я добавлю это сюда. Да, я включил трассировку, но мне кажется, что мне нужно будет прочитать КНИГУ, чтобы понять все, что данные трассировки пытаются мне сообщить. Тем не менее, я просмотрел информацию о трассировке, и единственное, что я не увидел, было что-то, что приводило к прерыванию сокета. Кажется, что это происходит без причины. (

...