Соединение с сокетом было прервано - CommunicationException - PullRequest
22 голосов
/ 09 августа 2010

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

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

Сценарий:

  • Кажется, у меня могут быть циклические ссылки в моей службе WCF, но использование "[DataContract (IsReference = true)]" "ничего не может сделать, чтобы это исправить.
  • Я получаюerror "Соединение с сокетом было прервано. Это может быть вызвано ошибкой при обработке вашего сообщения или превышением тайм-аута приема удаленным хостом, или проблемой основного сетевого ресурса. Тайм-аут локального сокета был '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;
    }
}

Ответы [ 6 ]

19 голосов
/ 01 августа 2013

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

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

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

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

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

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

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

3 голосов
/ 10 декабря 2013

Возникла проблема с длительным процессом инициализации, который вызывался из события 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);
2 голосов
/ 15 января 2016

Эта проблема также может возникать из-за того, что клиент 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, либо с помощью процедуры, позволяющей им сначала убедиться, что ведение журнала происходит при всех ошибках, и, во-вторых, обеспечить закрытие канала, когда ошибки не возникают, но прерываются, если исключение случается. Наконец, как указано в операторе using, вызывается окончательное удаление канала. Таким образом, ошибки, возникающие из-за неправильной очистки каналов, которые будут выглядеть как эта ошибка, будут предотвращены.

1 голос
/ 18 декабря 2015

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

0 голосов
/ 21 января 2014

Ошибка WCF:

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...