2016-04-19 16 views
0

Ich habe ein Problem mit meinem Programm. Ich habe einen Dienst erstellt, der seine Aktionen mit NLOG protokolliert. Neben diesem Dienst habe ich ein Tool erstellt, um diese Protokollierung zu erfassen und dem Benutzer anzuzeigen. Diese Verbindung basiert auf WSDualHTTPBinding.Zeitüberschreitung bei der Protokollierung von System.Net auf Trace-Ebene

Neben den Aktionen des Dienstes protokolliere ich auch [System.Net], [System.ServiceModel] und [System.Windows] für einen vollständigen Protokollbericht.

Jetzt bekomme ich die TimeOutException: Die Nachricht konnte nicht innerhalb der zugewiesenen Timeout von 00.01.01 übertragen werden. Im Übertragungsfenster des zuverlässigen Kanals war kein Speicherplatz verfügbar. etc ...

Ich habe herausgefunden, dass diese Ausnahme ausgelöst wird, wenn der LogLevel für das System.Net. * Trace festgelegt ist. Andernfalls wird die Ausnahme nicht ausgelöst.

Ich habe mehrere Lösungen versucht, wie das Timeout zu erhöhen; Einstellen der DefaultConnectionLimit; Einstellen des ServiceBehaviorAttribute und viele mehr. Keiner von ihnen arbeitete für mich ...

Könnte mir jemand dabei helfen?


Consoleapplication Service:

class Program 
{ 
    static void Main(string[] args) 
    { 
     IoC.Kernel.Bind<ILogging>().ToConstant(new Logging()); 

     try 
     { 
      //Normal binding 
      var binding = new BasicHttpBinding(); 
      binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; 
      binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows; 

      var host = new ServiceHost(typeof(Contract)); 
      host.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true; 

      var path = "http://address:port/IContract"; 
      host.AddServiceEndpoint(typeof(IContract), binding, path); 

      host.Open(); 

      //Duplex binding 
      var duplexBinding = new WSDualHttpBinding(); 
      duplexBinding.Security.Mode = WSDualHttpSecurityMode.Message; 
      duplexBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows; 

      var duplexHost = new ServiceHost(typeof(DuplexContract)); 
      duplexHost.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true; 

      var duplexPath = "http://address:port/IDuplexContract"; 
      duplexHost.AddServiceEndpoint(typeof(IDuplexContract), duplexBinding, duplexPath); 

      duplexHost.Open(); 
      IoC.Kernel.Get<ILogging>().Log("Listening......."); 
     } 
     catch (Exception ex) 
     { 
      IoC.Kernel.Get<ILogging>().Log(ex.ToString()); 
     } 
     Console.ReadLine(); 
    } 
} 

Schnittstellen Service:

[ServiceContract] 
public interface IContract 
{ 
    [OperationContract] 
    void Update(string i); 
} 

[ServiceContract(CallbackContract = typeof(IDuplexContractCallback), SessionMode = SessionMode.Required)] 
public interface IDuplexContract 
{ 
    [OperationContract(IsOneWay = true)] 
    void AddListener(); 
} 

public interface IDuplexContractCallback 
{ 
    [OperationContract(IsOneWay = true)] 
    void Logger(string obj); 
    [OperationContract(IsOneWay = true)] 
    void ReceivedCalculate(int i); 
} 

public interface ILogging 
{ 
    void Log(string message); 
    void AddObserver(Action<string> addEventLog); 
} 

Implementations Service:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
public class DuplexContract : IDuplexContract 
{ 
    public void AddListener() 
    { 
     IoC.Kernel.Get<ILogging>().AddObserver(OperationContext.Current.GetCallbackChannel<IDuplexContractCallback>().Logger); 
     IoC.Kernel.Get<ILogging>().Log("Added listener"); 
    } 
} 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
public class Contract : IContract 
{ 
    public void Update(string i) 
    { 
     IoC.Kernel.Get<ILogging>().Log(string.Format("Received: {0}", i)); 
    } 
} 

public class Logging : ILogging 
{ 
    public Logging() 
    { 
     if (LogManager.Configuration == null) 
     { 
      LogManager.Configuration = new LoggingConfiguration(); 
     } 

     Target consoleTarget; 
     consoleTarget = LogManager.Configuration.FindTargetByName(nameof(consoleTarget)); 
     if (consoleTarget == null) 
     { 
      consoleTarget = new ColoredConsoleTarget() 
      { 
       Layout = "${longdate} [${logger}] [${level:uppercase=true}]: ${message} ${onexception:inner=${newline} ${exception:format=ToString:maxInnerExceptionLevel=4:innerFormat=ToString:seperator=\r\n}}", 
       Name = nameof(consoleTarget), 
       UseDefaultRowHighlightingRules = false, 
      }; 
      (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Fatal"), ConsoleOutputColor.Magenta, ConsoleOutputColor.NoChange)); 
      (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Error"), ConsoleOutputColor.Red, ConsoleOutputColor.NoChange)); 
      (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Warn"), ConsoleOutputColor.Yellow, ConsoleOutputColor.NoChange)); 
      (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Info"), ConsoleOutputColor.White, ConsoleOutputColor.NoChange)); 
      (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Debug"), ConsoleOutputColor.Gray, ConsoleOutputColor.NoChange)); 
      (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Trace"), ConsoleOutputColor.DarkGray, ConsoleOutputColor.NoChange)); 
      LogManager.Configuration.AddTarget(consoleTarget); 
     } 

     UpdateRules(consoleTarget); 
     LogManager.ReconfigExistingLoggers(); 
    } 

    public void Log(string message) 
    { 
     LogManager.GetLogger("CustomLogger").Trace(message); 
    } 

    private void UpdateRules(Target target) 
    { 
     var rules = LogManager.Configuration.LoggingRules.Where(u => u.Targets.Contains(target)).ToList(); 
     rules.ForEach(u => LogManager.Configuration.LoggingRules.Remove(u)); 

     LogManager.Configuration.LoggingRules.Add(new LoggingRule("System.Net.*", LogLevel.Trace, target)); //<-- Throws the exception 
     LogManager.Configuration.LoggingRules.Add(new LoggingRule("System.ServiceModel.*", LogLevel.Trace, target)); 
     LogManager.Configuration.LoggingRules.Add(new LoggingRule("System.Windows.*", LogLevel.Trace, target)); 
     LogManager.Configuration.LoggingRules.Add(new LoggingRule("CustomLogger", LogLevel.Trace, target)); 
    } 

    public void AddObserver(Action<string> addEventLog) 
    { 
     Target duplexCallbackTarget; 
     duplexCallbackTarget = LogManager.Configuration.FindTargetByName(nameof(DuplexCallbackTarget)); 
     if (duplexCallbackTarget == null) 
     { 
      var layout = new XmlLayout(); 
      duplexCallbackTarget = new DuplexCallbackTarget() 
      { 
       Name = nameof(DuplexCallbackTarget), 
       Layout = layout, 
       CallbackAction = addEventLog, 
      }; 
      LogManager.Configuration.AddTarget(duplexCallbackTarget); 
     } 
     UpdateRules(duplexCallbackTarget); 
     LogManager.ReconfigExistingLoggers(); 
    } 
} 

[Target("DuplexCallback")] 
public class DuplexCallbackTarget : TargetWithLayout 
{ 
    /// <summary> 
    /// The callback action from the client event viewer. 
    /// </summary> 
    public Action<string> CallbackAction { get; set; } 

    /// <summary> 
    /// Writes the specified log event information. 
    /// </summary> 
    /// <param name="logEventInfo">The log event information.</param> 
    protected override void Write(LogEventInfo logEventInfo) 
    { 
     try 
     { 
      CallbackAction(logEventInfo.Message); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.ToString()); 
     } 
    } 
} 

//Ninject 
public static class IoC 
{ 
    public static IKernel Kernel = new StandardKernel(); 
} 

Implementierung Zuhörer:

public class ContractCallback : IDuplexContractCallback 
{ 
    public void Logger(string obj) 
    { 
     Console.WriteLine(string.Format("Client received: {0}", obj)); 
    } 

    public void ReceivedCalculate(int i) 
    { 
     Console.WriteLine(string.Format("Client received: {0}", i)); 
    } 
} 

ConsoleWindow Zuhörer:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine("Waiting for server to be ready..."); 
     Console.ReadLine(); 

     var binding = new WSDualHttpBinding(); 
     binding.Security.Mode = WSDualHttpSecurityMode.Message; 
     binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows; 

     var factory = new DuplexChannelFactory<IDuplexContract>(new InstanceContext(new ContractCallback()), binding, new EndpointAddress("http://address:port/IDuplexContract")); 
     var channel = factory.CreateChannel(); 
     channel.AddListener(); 
     Console.WriteLine("Listening at server...."); 
     Console.ReadLine(); 
    } 
} 

ConsoleWindow Auftraggeber:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine("Waiting for server & listener to be ready..."); 
     Console.ReadLine(); 

     var binding = new BasicHttpBinding(); 
     binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; 
     binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows; 

     var factory = new ChannelFactory<IContract>(binding, new EndpointAddress("http://address:port/IContract")); 
     var channel = factory.CreateChannel(); 

     while (true) 
     { 
      channel.Update(Console.ReadLine()); 
     } 
    } 
} 

Antwort

0

Das Problem ist eine Unendlichkeitsschleife. Dies wird von der System.Net-Klasse erstellt, da der Namespace System.Net meinen Aufruf an den nächsten Server mit der HTTP-Nachricht verfolgt, wenn ich meine Callback-Funktion aufruft. Dies wird protokolliert und an den Logger usw. usw. gesendet.

Verwandte Themen