NLog到WCF。关闭客户端在服务器上抛出SocketException

时间:2014-05-23 07:25:53

标签: wcf nlog socketexception

我一直在努力解决这个问题一整天,并且不知道如何解决这个问题。我已经尝试了各种方法来解决这个问题,但我不知所措。

我有一个项目,我试图使用NLog的LogReceiverServer在2台PC之间发送和接收消息。 I followed this example here。一切都工作正常,我的WCF服务正常启动,我的客户端正确启动,甚至发送消息从客户端到服务器的日志工作。但是,当我关闭客户端时,我会收到服务器为每个传输的消息抛出的SocketExceptions。我知道这是因为客户没有正确关闭频道。我无法找到必须关闭通道的位置,以防止我的服务器抛出异常。我已经读过要手动关闭我必须使用的频道

Channel.Close();

这是正确的,我会把它放在哪里?

我想阻止这些SocketExceptions。我找到了this,但这似乎不是正确的做法。如果我错了,请纠正我,但解决方案不会使用相同的原则吗?

除非我理解这完全错误......

使用配置文件(App.Config和NLog.Config)完成所有工作。

这是来自NLog.config的我的LogReceiverService目标:

<target xsi:type="LogReceiverService" 
        name="logreceiver" 
        endpointConfigurationName="LogReceiverClient" 
        endpointAddress="net.tcp://server:8888/NLogServices/LogReceiverServer/logreceiverserver" />

这是我的app.config中的端点:

<endpoint address="net.tcp://server:8888/NLogServices/LogReceiverServer/logreceiverserver" 
          binding="netTcpBinding" 
          bindingConfiguration="LogReceiverClient" 
          contract="NLog.LogReceiverService.ILogReceiverClient" 
          name="LogReceiverClient" />

非常感谢任何帮助或建议。

编辑:问题描述扩展

好的,首先,这是我的主机上的服务,就像我从here得到的那样:

/// <summary>
/// Log service server object that logs messages.
/// </summary>
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class LogReceiverServer : ILogReceiverServer
{
    public void ProcessLogMessages(NLogEvents nevents)
    {
        var events = nevents.ToEventInfo("Client.");

        foreach (var ev in events)
        {
            var logger = LogManager.GetLogger(ev.LoggerName);
            logger.Log(ev);
        }
    }
}

然后我创建了这个类,我继承了LogReceiverWebServiceTarget并覆盖了protected virtual WcfLogReceiverClient CreateWcfLogReceiverClient();方法。它与GitHub here上的内容完全相同,只不过我在ProcessLogMessagesCompleted事件中注册了我关闭&#39;客户端&#39;:

    [Target("wcftarget")]
    public class WcfTarget : LogReceiverWebServiceTarget
    {
        protected override WcfLogReceiverClient CreateWcfLogReceiverClient()
        {
            WcfLogReceiverClient client;

            if (string.IsNullOrEmpty(EndpointConfigurationName))
            {
                // endpoint not specified - use BasicHttpBinding
                Binding binding;

                if (UseBinaryEncoding)
                {
                    binding = new CustomBinding(new BinaryMessageEncodingBindingElement(), new HttpTransportBindingElement());
                }
                else
                {
                    binding = new BasicHttpBinding();
                }

                client = new WcfLogReceiverClient(binding, new EndpointAddress(EndpointAddress));
            }
            else
            {
                client = new WcfLogReceiverClient(EndpointConfigurationName, new EndpointAddress(EndpointAddress));

        /*commenting this out causes multiple socket exceptions on host*/
                client.ProcessLogMessagesCompleted += client_ProcessLogMessagesCompleted; 
            }
            return client;
        }

        private void client_ProcessLogMessagesCompleted(object sender, AsyncCompletedEventArgs e)
        {
            WcfLogReceiverClient client = sender as WcfLogReceiverClient;

            if (client.State == CommunicationState.Opened)
            {
                (sender as WcfLogReceiverClient).Close();
            }
        }
    }

NLog.config中的记录器是:

<logger name="*" writeTo="logreceiver" minlevel="Info" />

那么如果我尝试这样记录:

class Program
{
    private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

    private static void Main(string[] args)
    {
        logger.Info("foo");

    }
}

我的主机将此打印到Debug:

A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
A first chance exception of type 'System.ServiceModel.CommunicationException' occurred in System.ServiceModel.dll

这会在很长一段时间内对主机的性能产生什么影响?

1 个答案:

答案 0 :(得分:0)