2010-08-09 17 views
16

Originalmente:La conexión de socket fue abortado - CommunicationException

  • pensé que esto era un problema de referencia circular ........ resulta que no lo es.
  • El problema surgió al no haber configurado las configuraciones del servicio.
  • Como los valores predeterminados son muy bajos, el envío de muchos datos hará colapsar el servicio.

Escenario:

  • Parece que puedo tener referencias circulares en mi servicio WCF, pero utilizando "[DataContract (IsReference = true)]", no hace nada para ayudar a solucionarlo.
  • Recibo el error "Se canceló la conexión del socket. Esto podría deberse a un error al procesar su mensaje o un tiempo de espera de recepción excedido por el host remoto o un problema de recursos de red subyacente. : 00 '. "
  • ¿Me he perdido algo?

Código:

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

Pensamientos:

  • Me pregunto si es porque tengo una FuturesAsset clase, que tiene una propiedad de tipo BindableDictionary (Esto es una aduana OBJECT), y esa propiedad contiene una lista de FuturesLinesAssets.
  • ver más abajo:

Padres:

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

Niño:

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; 
    } 
} 
+0

¿Cómo se obtiene de 'Error de socket' a una referencia circular? ¿Tiene algún mensaje de error que pueda agregar a la publicación? –

+0

Porque cuando busqué en Google el mensaje de error obtuve muchos resultados hablando de referencias circulares. Además, el error solo ocurre cuando intento enviar ALOT de datos, de lo contrario funciona bien. – Goober

Respuesta

11

esa excepción no está relacionado con la Circular de referencia, es sólo puramente agote el tiempo a medida que tratan bombee toneladas de datos por el cable.

Los valores predeterminados que vienen con WCF son muy bajos (creo que se han cambiado en WCF 4). Tiene una lectura de estas dos publicaciones en el blog, deben darle una idea sobre cómo dethrottle su servicio:

Creating high performance WCF services

How to throttle a Wcf service, help prevent DoS attacks, and maintain Wcf scalability

actualización: También, hay una serie de diferentes tiempos de espera en la configuración de WCF y dependiendo de si es el cliente o servidor del que está hablando, necesita actualizar una cláusula de tiempo de espera diferente ... lea esto thread sobre lo que significa cada uno y podrá averiguar cuál necesita para subir de nivel. O, puede establecer cada tiempo de espera en int.max si realmente no le importa si una llamada puede tardar bastante tiempo en completarse.

+0

¡FANTÁSTICO ERES CORRECTO MI BUEN HOMBRE! – Goober

+0

Maldita sea, el segundo enlace está muerto. – Gallen

+0

¿Hay un espejo para el segundo enlace? – CodeSlinger512

13

Este error puede deberse a varias cosas. Si bien fue un problema de tiempo en este caso, por lo general no tiene nada que ver con los tiempos, especialmente si el error se recibe de inmediato. Las posibles razones son:

  • Los objetos utilizados como parámetros o tipos de devolución en su contrato no tienen constructores sin parámetros y no están decorados con el atributo DataContract. Compruebe las clases utilizadas como parámetros o tipos de devolución, pero también todos los tipos utilizados por las propiedades públicas de esas clases. Si implementa un constructor con parámetros para una de esas clases, el compilador ya no agregará el constructor sin parámetros predeterminado, por lo que deberá agregarlo usted mismo.
  • Los límites predeterminados definidos en la configuración del servicio son demasiado bajos (MaxItemsInObjectGraph, MaxReceivedMessageSize, MaxBufferPoolSize, MaxBufferSize, MaxArrayLength).
  • Algunas propiedades públicas de sus objetos DataContract son de solo lectura. Asegúrese de que todas las propiedades públicas tengan getters y setters.
+0

Tuve este error con el objeto de retorno que contiene propiedades con decimales fuera de límites y enumeraciones con valores no válidos. – pauloya

+1

Pasar un 'DataTable' sin un' .TableName', o una tabla vacía sin datos ('new DataTable()') también puede causar esto. –

+2

Tuve este error y la causa principal fue WCF. Cuando cambié de WCF, el problema desapareció. – pettys

2

tenido este problema con un proceso a largo intialisation que estaba siendo llamado desde el evento OnStart de un anfitrión de instalación de servicios de Windows. Se solucionó estableciendo el modo de seguridad y los tiempos de espera para el enlace 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); 
0

El error WCF:

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was ...

donde los tiempos de espera reportados son muy cerca de 1 minuto (por ejemplo 00:00:59.9680000) o 1 minutos exactamente (es decir 00:01:00) puede ser causada por el mensaje de ser demasiado grande y exceeding the settings for the binding .

Esto se puede solucionar mediante el aumento de los valores en el archivo de configuración, por ejemplo .:

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

(valores de ejemplo solamente, es posible que desee sintonizar ellos).

1

Se produjo esta excepción cuando devolvía un objeto con colecciones de IEnumerable y se produjo una excepción mientras se recuperaba uno de los miembros de la colección. En ese momento, es demasiado tarde para capturarlo en su código y, presumiblemente, WCF está diseñado para desconectar el socket en ese caso porque también es demasiado tarde para informar una excepción al cliente, dado que ya ha comenzado a transmitir los resultados.

0

Este problema también puede deberse a que no limpia el cliente WCF cuando termina de usarlo. En nuestro sistema, utilizamos el patrón desechable junto con el ajuste de todas las llamadas a funciones en el sistema para permitir la limpieza y el registro adecuados. Nosotros usamos una versión de la siguiente clase:

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

} 

Cada WCF llame hacemos en nuestro servicio es a través de una clase de interfaz se define como la siguiente:

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

Usando este modelo, todos WCF pone en el sistema está envuelto con el método de Función o el Procedimiento, lo que les permite primero garantizar que el registro se produzca en todos los errores, y segundo para garantizar que el canal se cierre cuando no se producen errores pero se anula si ocurre una excepción. Finalmente, como está en una declaración de uso, se llama a la disposición final del canal. De esta forma, se evitarán los errores que ocurran debido a que los canales no se limpian correctamente, lo que se parecerá a este error.

Cuestiones relacionadas