La détection de Client de la Mort dans WCF Contrats Duplex

Je suis en train de construire une architecture SOA, où les clients peuvent effectuer des requêtes de longue durée sur le serveur et le serveur répond en utilisant une fonction de rappel.

Je voudrais être en mesure de détecter si le client se déconnecte (par l'utilisateur a lancé la fermeture, exception non gérée ou de la perte de connectivité réseau) pour que le serveur peut choisir d'annuler le cher demande.

Je me suis mise à l'essai d'une variété de cas d'insuffisance, mais je n'arrive pas à obtenir certains gestionnaires d'événements à feu.

Testé Cas De:
Tuer les Processus du Client Après la demande.
À l'aide d'un programme comme CurrPorts pour fermer la Connexion TCP.

Code De Test:

using System;
using System.ServiceModel;
using System.Threading;
namespace WCFICommunicationObjectExperiments
{
class Program
{
static void Main(string[] args)
{
var binding = new NetTcpBinding(SecurityMode.None);
var serviceHost = new ServiceHost(typeof (Server));
serviceHost.AddServiceEndpoint(typeof (IServer), binding, "net.tcp://localhost:5000/Server");
serviceHost.Open();
Console.WriteLine("Host is running, press <ENTER> to exit.");
Console.ReadLine();
}
}
[ServiceContract(CallbackContract = typeof(IClient))]
public interface IServer
{
[OperationContract]
void StartProcessing(string Query);
}
public interface IClient
{
[OperationContract]
void RecieveResults(string Results);
}
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Server : IServer
{
public void StartProcessing(string Query)
{
Thread.Sleep(5000);
//Callback Channel
var clientCallback = OperationContext.Current.GetCallbackChannel<IClient>();
var clientCallbackCommunicationObject = ((ICommunicationObject) clientCallback);
EventHandler faultedHandlerCallback = (o, s) => Console.WriteLine("Client Channel Faulted.");
EventHandler closedHandlerCallback = (o, s) => Console.WriteLine("Client Channel Closed.");
clientCallbackCommunicationObject.Faulted += faultedHandlerCallback;
clientCallbackCommunicationObject.Closed += closedHandlerCallback;
//Request Channel
var requestChannel = OperationContext.Current.Channel;
EventHandler faultedHandlerRequest = (o, s) => Console.WriteLine("Request Channel Faulted.");
EventHandler closedHandlerRequest = (o, s) => Console.WriteLine("Request Channel Closed.");
requestChannel.Faulted += faultedHandlerRequest;
requestChannel.Closed += closedHandlerRequest;
try
{
clientCallback.RecieveResults("42.");
}
catch (CommunicationObjectAbortedException ex)
{
Console.WriteLine("Client Aborted the connection");
}
catch (CommunicationObjectFaultedException ex)
{
Console.WriteLine("Client Died.");
}
clientCallbackCommunicationObject.Faulted -= faultedHandlerCallback;
clientCallbackCommunicationObject.Faulted -= closedHandlerCallback;
requestChannel.Faulted -= faultedHandlerRequest;
requestChannel.Closed -= closedHandlerRequest;
}
}
public class ClientToTestStates : IClient
{
private IServer m_Server;
private readonly ManualResetEvent m_ReceivedEvent = new ManualResetEvent(false);
private readonly ManualResetEvent m_ChannelFaulted = new ManualResetEvent(false);
private readonly ManualResetEvent m_ChannelClosed = new ManualResetEvent(false);
public ClientToTestStates()
{
var binding = new NetTcpBinding(SecurityMode.None);
var channelFactory = new DuplexChannelFactory<IServer>(this, binding, new EndpointAddress("net.tcp://localhost:5000/Server"));
m_Server = channelFactory.CreateChannel();
((ICommunicationObject)m_Server).Open();
((ICommunicationObject)m_Server).Faulted += ChannelFaulted;
((ICommunicationObject)m_Server).Closed += ChannelClosed;
m_Server.StartProcessing("What is the answer?");
WaitHandle.WaitAny(new WaitHandle[] {m_ReceivedEvent, m_ChannelFaulted, m_ChannelClosed});
}
void ChannelFaulted(object sender, EventArgs e)
{
m_ChannelFaulted.Set();
Console.WriteLine("Channel Faulted.");
}
void ChannelClosed(object sender, EventArgs e)
{
m_ChannelClosed.Set();
Console.WriteLine("Channel Closed.");
}
public void RecieveResults(string results)
{
m_ReceivedEvent.Set();
Console.WriteLine("Recieved Results {0}", results);
}
}
}

Quelle est la meilleure pratique pour gérer ce genre de cas? J'aimerais être en mesure d'utiliser la connexion tcp sous-jacente à détecter certaines de ces choses.

  • Avez-vous essayé de retourner sur la Fiabilité? TCP fournit point-à-point de la fiabilité. <br> Message de la fiabilité (via WS-Reliability) fournit de bout en bout de la fiabilité. <br> Et à mon tour, je crois que vous aviserons lorsque l'une des parties ‘disparaît’ sans ménagement. Pour les transports qui le prennent en charge, il est préférable de toujours tourner sur la fiabilité, même si certains le réseau de ‘goo’ ne peut pas le soutenir
InformationsquelleAutor Sindhudweep | 2009-09-15