关闭双工通道仍会在跟踪中产生错误

时间:2013-06-21 22:40:16

标签: wcf tcp publish-subscribe tracing duplex-channel

我在发布/订阅模式中使用了双工WCF通道。我无法弄清楚如何干净地断开客户端而不会在跟踪中产生错误。该错误不会影响应用程序,但会显示在跟踪日志中。由于此预期错误消息填满了我们的日志,因此很难找出其他问题。

服务器端日志中显示的错误:

“远程主机强行关闭现有连接” System.ServiceModel.Channels.SocketConnection.HandleReceiveAsyncCompleted() System.ServiceModel.Channels.SocketConnection.OnReceiveAsync(Object sender,SocketAsyncEventArgs eventArgs) System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncFailure(SocketError socketError,Int32 bytesTransferred,SocketFlags flags) System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode,UInt32 numBytes,NativeOverlapped * nativeOverlapped) System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode,UInt32 numBytes,NativeOverlapped * pOVERLAP)

server code:
        public static void StartHost()
        {
           var startTime = DateTime.Now;
        var duplex = new ServiceHost(typeof(HostChannel));
        try
        {
            duplex.AddServiceEndpoint(typeof(IHostChannel),
                CreateTpcBinding(),
               AppConfiguration.SchedulerHostChannel);
            duplex.Open();

            _duplex = duplex;

        }
        catch (Exception e)
        {
            log.LogError("Error acquiring HostChannel:" + e);
            if (duplex.State == CommunicationState.Faulted)
                duplex.Abort();
            duplex.Close();
            throw;
        }
    }

private static NetTcpBinding CreateTpcBinding()
    {
        return new NetTcpBinding()
        {
            ReliableSession = new OptionalReliableSession() { InactivityTimeout = TimeSpan.FromDays(5) },
            ReceiveTimeout = TimeSpan.FromDays(5),
            ReaderQuotas = new XmlDictionaryReaderQuotas() { MaxStringContentLength = 5242880 }
        };
    }
    /// <summary>
    /// First method the client calls 
    /// </summary>
    public void EstablishConnection()
    {
        var channelBinder = ServiceLocator.Current.GetInstance<RemoteResourceManager>();
        var remoteChannel = OperationContext.Current.GetCallbackChannel<IRemoteChannel>();
        _processHandle = channelBinder.RegisterRemoteChannel(remoteChannel);
    }
    /// <summary>
    /// Last method that is called
    /// </summary>
    public void NotifyComplete()
    {
        _processHandle.Events.OnCompleted(_processHandle.RemoteChannel, new EventArgs());


        log.LogInfo("Try to clean callback channel");
        ((IClientChannel)_processHandle.RemoteChannel).Close();
        ((IClientChannel)OperationContext.Current.GetCallbackChannel<IRemoteChannel>()).Close();
        log.LogInfo("Cleaned callback channel");


    }

客户端回调接口:

public interface IRemoteChannel
{
    [OperationContract(IsOneWay = true)]
    void StartTask(TaskDefinition taskDefinition);
    [OperationContract(IsOneWay = true)]
    void RequestCancelTask();
    [OperationContract(IsOneWay = true)]
    void HealthCheck();
} 

客户端在调用NotifyComplete后清理代码

 if (_proxy is IClientChannel)
            channel = ((IClientChannel)_proxy);

        try
        {
            if (channel != null)
            {
                if (channel.State != CommunicationState.Faulted)
                {
                    channel.Close();
                }
                else
                {
                    channel.Abort();
                }
            }
        }
        catch (CommunicationException e)
        {
            channel.Abort();
        }
        catch (TimeoutException e)
        {
            channel.Abort();
        }
        catch (Exception e)
        {
            channel.Abort();
            throw;
        }
        finally
        {
            _proxy = null;
        }

0 个答案:

没有答案