简体   繁体   中英

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? 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.

You can utilize various events on the IClientChannel to monitor what happens with the connection. For your case the Faulted event seems the most appropriate. 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

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.

if the service is disconnected and the client attempts to call the service you should try to catch an 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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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