Rajat Mehta
Rajat Mehta

Reputation: 201

WCF duplex nettcp channel not faulting

Problem

I have this strange problem. I am hosting a WCF server in a console app: Console.WriteLine("Press 'q' to quit.");

            var serviceHost = new ServiceHost(typeof(MessageService));
            serviceHost.Open();
            while (Console.ReadKey().KeyChar != 'q')
            {
            }
            serviceHost.Close();

it exposes two endpoint for publish and subscribe (duplex binding) When I stop or exit the console app, I never receive channel faulted at the client end. I would like client to be informed is server is down. Any idea what is going wrong here?

All I want is either of the following event to be raised when console app goes down:

    msgsvc.InnerDuplexChannel.Faulted += InnerDuplexChannelOnFaulted;
    msgsvc.InnerChannel.Faulted += InnerChannelOnFaulted;

Upvotes: 0

Views: 820

Answers (3)

eric frazer
eric frazer

Reputation: 1649

if you're the client, and subscribe to all 3 events, IClientChannel's Closing, Closed, and Faulted, you should see at the very least the Closing and Closed events if you close the service console app. I'm not sure why. if you're closing up correctly, you would think you'd see Faulted. I'm using tcp.net full duplex channels and I see these events just fine. Keep in mind it's in 2017, so things might have changed since then, but I rely on these events all the time in my code. For those people who says the duplex model doesn't see Closing of channels, I'm not understanding that.

Upvotes: 0

SalientBrain
SalientBrain

Reputation: 2541

AFAIK tcp channel is quite responsive to (persistant) connection problems, but you can use callback to notify clients before server becomes unavailable. From client side you can use some dummy ping/poke method 'OnTimer' to get actual connection state/keep channel alive. It's good to recover client proxy (reconnect) at that point, I suppose. If service provides metadata endpoint, you also can call svcutil for trial connection or retrieve metadata programmatically:

  Uri mexAddress = new Uri("http://localhost:5000/myservice");
  var mexClient = new MetadataExchangeClient(mexAddress, MetadataExchangeClientMode.HttpGet);
  MetadataSet metadata = mexClient.GetMetadata();
  MetadataImporter importer = new WsdlImporter(metadata);
  ServiceEndpointCollection endpoints = importer.ImportAllEndpoints();

  ContractDescription description =
  ContractDescription.GetContract(typeof(IMyContract));
  bool contractSupported = endpoints.Any(endpoint =>
  endpoint.Contract.Namespace == description.Namespace &&
  endpoint.Contract.Name == description.Name);

or

ServiceEndpointCollection endpoints = MetadataResolver.Resolve(typeof(IMyContract), mexAddress, MetadataExchangeClientMode.HttpGet)

Upvotes: 0

Steven Licht
Steven Licht

Reputation: 770

From MSDN: The duplex model does not automatically detect when a service or client closes its channel. So if a service unexpectedly terminates, by default the service will not be notified, or if a client unexpectedly terminates, the service will not be notified. Clients and services can implement their own protocol to notify each other if they so choose.

Upvotes: 1

Related Questions