繁体   English   中英

使用WCF回调时,客户端如何知道服务器是否已中断

[英]When using WCF callbacks how do clients know if the server has been interrupted

如果我使用提供回调的WCF服务创建了一个客户端,并且有多个客户端进行注册以接收事件,那么这些客户端如何知道服务是否中断或关闭? 目前,他们目前正处于等待状态,永远不会触发。

我以为我可以实施某种轮询(这就是我试图摆脱的轮询)。 但是,即使进行轮询也似乎无法解决问题。 例如,如果我每30秒轮询一次,但服务或应用程序池在下一次检查之前重新启动,则尽管服务器已失去对它们的引用,客户端仍会认为一切正常。

您可以利用IClientChannel上的各种事件来监视连接发生的情况。 对于您而言, Faulted事件似乎是最合适的。 但是,还有其他事件可能对您有用。

    _proxy.InnerChannel.Opening += OnChannelOpening;
    _proxy.InnerChannel.Opened += OnChannelOpened;
    _proxy.InnerChannel.Faulted += OnChannelFaulted;
    _proxy.InnerChannel.UnknownMessageReceived += OnChannelUnknownMessageReceived;
    _proxy.InnerChannel.Closing += OnChannelClosing;
    _proxy.InnerChannel.Closed += OnChannelClosed;

看看我写来回答另一个问题的这个存储库: https : //github.com/Aelphaeis/MyWcfDuplexPipeExample/tree/MultiClient

在此存储库中,有一个双工连接和两个客户端。

如果客户端断开连接,并且当您尝试调用客户端回调函数时服务尝试访问客户端,则应捕获CommunicationObjectAbortedException。

如果服务已断开连接,并且客户端尝试调用该服务,则应尝试捕获EndPointNotFoundException。

public class MyServiceClient: IMyService, IDisposable
{
    DuplexChannelFactory<IMyService> myServiceFactory { get; set; }

    public MyServiceClient(IMyServiceCallback Callback)
    {
        InstanceContext site = new InstanceContext(Callback);
        NetNamedPipeBinding binding = new NetNamedPipeBinding();
        EndpointAddress endpointAddress = new EndpointAddress(Constants.myPipeService + @"/" + Constants.myPipeServiceName);

        myServiceFactory = new DuplexChannelFactory<IMyService>(site, binding, endpointAddress);
        Init();
    }
    public void Init()
    {
        myServiceFactory.CreateChannel().Init();//EndPointNotFoundException Thrown here
    }

    public void DoWork()
    {
        myServiceFactory.CreateChannel().DoWork();//EndPointNotFoundException Thrown here
    }

    public void Dispose()
    {
        myServiceFactory.Close();
    }
}

服务

public class MyServiceServer : IDisposable
{
    public Boolean IsDisposed { get; private set; }
    ServiceHost host { get; set; }
    MyService service;
    public void Open()
    {
        if (host != null)
            Dispose();

        IsDisposed = false;
        service = new MyService();
        host = new ServiceHost(service, new Uri(Constants.myPipeService));
        host.AddServiceEndpoint(typeof(IMyService), new NetNamedPipeBinding(), Constants.myPipeServiceName);

        host.BeginOpen(OnOpen, host);
    }

    public void Msg(int ClientId)
    {
        foreach (var cb in service.Callbacks)
            if (cb.GetClientId() == ClientId) // CommunicationObjectAbortedException here
                cb.RecieveMessage("We have called you choosen one");
    }

    public void Close()
    {
        host.BeginClose(OnClose, host);
    }

    public void Dispose()
    {
        ((IDisposable)host).Dispose();
        IsDisposed = true;
        host = null;
    }

    void OnOpen(IAsyncResult ar)
    {
        ServiceHost service = (ServiceHost)ar.AsyncState;
        service.EndOpen(ar);
    }
    void OnClose(IAsyncResult ar)
    {
        ServiceHost service = (ServiceHost)ar.AsyncState;
        service.EndClose(ar);
        Dispose();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM