简体   繁体   English

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

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

If I create a WCF Service with that offers callbacks and I have several clients that register to receive events with it, how do those clients know if the service is interrupted or goes down? 如果我使用提供回调的WCF服务创建了一个客户端,并且有多个客户端进行注册以接收事件,那么这些客户端如何知道服务是否中断或关闭? At the moment they are currently just left hanging waiting for an event that will never fire. 目前,他们目前正处于等待状态,永远不会触发。

I thought perhaps I could implement some sort of polling (which is what I was trying to get away from). 我以为我可以实施某种轮询(这就是我试图摆脱的轮询)。 But even polling seems like a poor fix. 但是,即使进行轮询也似乎无法解决问题。 For instance if I poll every 30 seconds but the service or the app pool is restarted before the next check then the clients will think everything is fine despite the fact that the server has lost reference to them. 例如,如果我每30秒轮询一次,但服务或应用程序池在下一次检查之前重新启动,则尽管服务器已失去对它们的引用,客户端仍会认为一切正常。

You can utilize various events on the IClientChannel to monitor what happens with the connection. 您可以利用IClientChannel上的各种事件来监视连接发生的情况。 For your case the Faulted event seems the most appropriate. 对于您而言, Faulted事件似乎是最合适的。 But there are also other events you may find useful. 但是,还有其他事件可能对您有用。

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

Take a look at this repository I wrote to answer another question : https://github.com/Aelphaeis/MyWcfDuplexPipeExample/tree/MultiClient 看看我写来回答另一个问题的这个存储库: https : //github.com/Aelphaeis/MyWcfDuplexPipeExample/tree/MultiClient

In this repository there is a duplex connection and two clients. 在此存储库中,有一个双工连接和两个客户端。

If a client disconnects and the services attempts to access a client when you attempt to call the client callback function you will should catch a CommunicationObjectAbortedException. 如果客户端断开连接,并且当您尝试调用客户端回调函数时服务尝试访问客户端,则应捕获CommunicationObjectAbortedException。

if the service is disconnected and the client attempts to call the service you should try to catch an EndPointNotFoundException. 如果服务已断开连接,并且客户端尝试调用该服务,则应尝试捕获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();
    }
}

Service 服务

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