简体   繁体   中英

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;

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.

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)

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.

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