Подтвердить что ты не робот

Соединение сокета было прервано - CommunicationException

Первоначально:

  • Я думал, что это круговая справочная проблема........ не получается.
  • Проблема возникла из-за того, что конфигурации конфигурации вообще не настроены.
  • Поскольку значения по умолчанию очень низкие, отправка большого количества данных приведет к сбою службы.

Сценарий:

  • Кажется, у меня могут быть круговые ссылки в моей службе WCF, но с помощью "[DataContract (IsReference = true)]" ничего не помогает, чтобы исправить это.
  • Я получаю сообщение об ошибке "Соединение сокета было прервано. Это может быть вызвано ошибкой обработки вашего сообщения или превышением тайм-аута приема удаленным хостом или основной проблемой сетевого ресурса. Локальный тайм-аут гнезда был" 00: 01:. 00' "
  • Я что-то пропустил?

Код:

[DataContract(IsReference=true)]
public class Message
{
    [DataMember]
    public string TopicName { get; set; }

    [DataMember]
    public string EventData { get; set; }

    [DataMember]
    public SerializableDictionary<string, FuturesLineAsset> FuturesLineDictionary { get; set ; }
}

Мысли:

  • Интересно, потому что у меня есть класс FuturesAsset, который имеет свойство типа BindableDictionary (ЭТО ТАМОЖЕННЫЙ ОБЪЕКТ), и это свойство содержит список FuturesLinesAssets.
  • См. ниже:

Родитель:

public class FuturesAsset
{
    public string AssetName { get; set; }
    public BindableDictionary<string, FuturesLineAsset> AssetLines { get; private set; }

    public FuturesAsset()
    {
        AssetLines = new BindableDictionary<string, FuturesLineAsset>();
    }

    public FuturesAsset(string assetName)
    {
        AssetLines = new BindableDictionary<string, FuturesLineAsset>();
        AssetName = assetName;
    }
}

Ребенок:

public class FuturesLineAsset
{

    public string ReferenceAsset { get; set; }
    public string MID { get; set; }
    public double LivePrice { get; set; }
    public DateTime UpdateTime { get; set; }
    public DateTime LastContributedTime { get; set; }
    public double Spread { get; set; }
    public double Correlation { get; set; }
    public DateTime Maturity { get; set; }
    public double ReferenceCurve { get; set; }

    public FuturesLineAsset(string mID, string referenceAsset, double livePrice)
    {
        MID = mID;
        ReferenceAsset = referenceAsset;
        ReutersLivePrice = livePrice;
    }
}
4b9b3361

Ответ 1

это исключение не связано с Circular Reference, это просто чистое время, когда вы пытаетесь перекачивать тонны данных по проводу.

Значения по умолчанию, которые поставляются с WCF, очень низок (они были изменены в WCF 4, я считаю). Прочитайте эти два сообщения в блоге, они должны дать вам представление о том, как отбросить вашу службу:

Создание высокопроизводительных служб WCF

Как отключить службу Wcf, помочь предотвратить атаки DoS и поддерживать масштабируемость Wcf

Обновить: также существует множество различных тайм-аутов в конфигурации WCF и в зависимости от того, является ли это клиентом или сервером, о котором вы говорите, вам нужно обновить другое предложение тайм-аута... прочитайте этот thread о том, что каждый из них означает, и вы должны выяснить, какой из них вам нужно поднять. Или, вы можете просто установить каждый таймаут на int.max, если вам все равно, если вызов может занять некоторое время.

Ответ 2

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

  • Объекты, используемые в качестве параметров или возвращаемых типов в вашем контракте, не имеют конструкторов без параметров и не украшены атрибутом DataContract. Проверьте классы, используемые в качестве параметров или возвращаемых типов, а также все типы, используемые общедоступными свойствами этих классов. Если вы реализуете конструктор с параметрами для одного из этих классов, компилятор больше не будет добавлять конструктор без параметров по умолчанию, поэтому вам нужно будет добавить это самостоятельно.
  • Ограничения по умолчанию, определенные в конфигурации службы, слишком низки (MaxItemsInObjectGraph, MaxReceivedMessageSize, MaxBufferPoolSize, MaxBufferSize, MaxArrayLength).
  • Некоторые общедоступные свойства ваших объектов DataContract доступны только для чтения. Убедитесь, что все общедоступные свойства имеют как получатели, так и сеттеры.

Ответ 3

У этой проблемы был длинный процесс инициализации, который вызывался из события OnStart установщика Windows Service Host. Исправлено установкой режима безопасности и тайм-аутов для привязки TCP.

            // Create a channel factory.
            NetTcpBinding b = new NetTcpBinding();
            b.Security.Mode = SecurityMode.Transport;
            b.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
            b.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;

            b.MaxReceivedMessageSize = 1000000;
            b.OpenTimeout = TimeSpan.FromMinutes(2);
            b.SendTimeout = TimeSpan.FromMinutes(2);
            b.ReceiveTimeout = TimeSpan.FromMinutes(10);

Ответ 4

Эта проблема также может быть вызвана не очисткой клиента WCF, когда вы его используете. В нашей системе мы используем одноразовый шаблон вместе с переносом всех вызовов функций в систему, чтобы обеспечить правильную очистку и протоколирование. Мы используем версию следующего класса:

    public class WcfWrapper : IDisposable
    {
        private readonly OperationContextScope _operationContextScope;
        private readonly IClientChannel _clientChannel;

        public WcfWrapper(IClientChannel clientChannel)
        {
            _clientChannel = clientChannel;
            _operationContextScope = new OperationContextScope(_clientChannel);
        }



        public void Dispose()
        {
            _operationContextScope.Dispose();
        }


        public T Function<T>(Func<T> func)
        {
            try
            {
                var result = func();
                _clientChannel.Close();
                return result;
            }
            catch (Exception ex)
            {
                KTrace.Error(ex);
                _clientChannel.Abort();
                throw;
            }

        }

        public void Procedure(Action action)
        {
            try
            {
                action();
                _clientChannel.Close();
            }
            catch (Exception ex)
            {
                KTrace.Error(ex);
                _clientChannel.Abort();
                throw;
            }
        }
    }

}

Каждый вызов WCF, который мы делаем в нашу службу, осуществляется через определенный класс интерфейса, такой как следующий:

    public sealed class WcfLoginManager : ILoginManager
    {
        private static LoginManagerClient GetWcfClient()
        {
            return 
                new LoginManagerClient(
                    WcfBindingHelper.GetBinding(),
                    WcfBindingHelper.GetEndpointAddress(ServiceUrls.LoginManagerUri));

        }

        public LoginResponse Login(LoginRequest request)
        {
            using(var loginManagerClient = GetWcfClient())
            using (var slice = new WcfWrapper(loginManagerClient.InnerChannel))
            {
                DSTicket ticket;
                DSAccount account;
                return slice.Function(() => new LoginResponse(loginManagerClient.Login(request.accountName, request.credentials, out ticket, out account), ticket, account));
            }
        }
    }

Используя этот шаблон, все вызовы WCF в систему обертываются либо методом Function, либо методом Procedure, позволяя им сначала обеспечить ведение журнала при всех ошибках, а во-вторых, чтобы гарантировать, что канал закрыт, когда ошибки не произойдут, но прерваны, если исключение происходит. Наконец, как и в используемом утверждении, вызывается окончательное удаление канала. Таким образом, будут предотвращены ошибки, возникающие из-за неправильной очистки каналов, которые будут выглядеть как эта ошибка.

Ответ 5

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

Ответ 6

Ошибка WCF:

Соединение сокетов было прервано. Это может быть вызвано ошибкой обработка вашего сообщения или превышение тайм-аута приема удаленный хост или проблема с сетевым ресурсом. Локальный разъем таймаут был...

где время ожидания составляет очень близкое к 1 минуте (например, 00:00:59.9680000) или точно 1 минуту (т.е. 00:01:00), может быть вызвано слишком большим сообщением и превышает настройки привязки.

Это можно устранить, увеличив значения в файле конфигурации, например:

<binding name="MyWcfBinding" 
         maxReceivedMessageSize="10000000" 
         maxBufferSize="10000000" 
         maxBufferPoolSize="10000000" />

(только примерные значения, вы можете настроить их).

Ответ 7

В моем случае я пытался создать экземпляр Wcf с net tcp. Итак, если в разделе привязок вашего web.config у вас настроен "netTcpBinding", как это

<bindings>
    <netTcpBinding>
        <binding name="bindingName" closeTimeout="01:10:00" openTimeout="01:10:00" receiveTimeout="01:10:00" sendTimeout="01:10:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647" portSharingEnabled="true">
            <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="16384"/>
            <reliableSession ordered="true" inactivityTimeout="01:10:00" enabled="false"/>
            <security mode="None"/>
        </binding>
    </netTcpBinding>
</bindings>

Затем вам нужно сконфигурировать раздел службы, определяя конечные точки с их атрибутом контракта, используя пространство имен интерфейса ваших служб, и добавить baseAddres, что-то вроде этого

<services>
  <service behaviorConfiguration="sgiBehavior" name="Enterprise.Tecnic.SGI.OP.Wcf.OP">
    <endpoint address="" behaviorConfiguration="endPointBehavior" binding="webHttpBinding" bindingConfiguration="BindingWebHttp" name="endPointHttp" contract="Enterprise.Tecnic.SGI.OP.Interface.IOP"/>
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
    <endpoint address="" binding="netTcpBinding" bindingConfiguration="bindingName"
      name="EndpointNetTcp" contract="Enterprise.Tecnic.SGI.OP.Interface.IOP" />

    <host>
      <baseAddresses>
        <!--  <add baseAddress="http://localhost:61217/OP.svc"/> -->
        <add baseAddress="http://www.Enterprise.com/Tecnic/SGI/OP/" />
        <add baseAddress="net.tcp://www.Enterprise.com/Tecnic/SGI/OP/" />           
      </baseAddresses>
    </host>
  </service>
</services>

Я провел два дня с этой проблемой, но это было единственное, что сработало для меня.