none
Handle Disconected Event Of Client RRS feed

  • Pergunta

  • Pessoal resolver trazer essa discussão a um ambito maior, venho discutindo isso com o Israel e até o momento não consegui achar uma solução.

    Como faço para capturar o evento disconected de um Client que foi forçado a ser fechado sem mesmo ter a possibilidade de invocar uma chamada do lado do cliente para informar ao host que o mesmo esta sendo fechado, ou seja, CTRL+ALT+DEL Kill Process na Aplicação cliente e o servidor sem ter a chance de ter um CallBack do cliente identificar que o mesmo nao esta mais conectado.

    Lembrando que ja tentei tudo que esteja envolvido com algo desse tipo - http://www.israelaece.com/post/Dectetando-a-desconexao.aspx

    Obrigado.

    terça-feira, 20 de julho de 2010 17:03

Respostas

  • Boas Francis,

    Conforme eu mencionei no meu último comentário no blog, tente implementar a interface IInputSessionShutdown, e com isso você a adiciona no DispatcherRuntime, como eu faço no exemplo abaixo:

    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(Servico), new Uri[] { new Uri("net.tcp://localhost:8382") }))
            {
                host.Description.Behaviors.Add(new ServiceMetadataBehavior());
                host.AddServiceEndpoint(typeof(IContrato), new NetTcpBinding(), "srv");
                host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");

                host.Open();
                Console.ReadLine();
            }
        }
    }

    [ServiceContract]
    public interface IContrato
    {
        [OperationContract]
        string Ping(string value);
    }

    [SessionShutdownBehavior]
    public class Servico : IContrato
    {
        public string Ping(string value)
        {
            Console.WriteLine("Ping");
            return value;
        }
    }

    public class SessionShutdownTrigger : IInputSessionShutdown
    {
        public void ChannelFaulted(IDuplexContextChannel channel)
        {
            Console.WriteLine("ChannelFaulted");
        }

        public void DoneReceiving(IDuplexContextChannel channel)
        {
            Console.WriteLine("DoneReceiving");
        }
    }

    public class SessionShutdownBehaviorAttribute : Attribute, IContractBehavior, IContractBehaviorAttribute
    {
        public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }

        public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) { }

        public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
        {
            dispatchRuntime.InputSessionShutdownHandlers.Add(new SessionShutdownTrigger());
        }

        public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) { }

        public Type TargetContract
        {
            get
            {
                return typeof(IContrato);
            }
        }
    }

    Com esse recurso, acho que você conseguirá ser notificando quando você der um shutdown no seu processo. Se der certo, tudo o que você precisará fazer é encontrar o seu cliente e removê-lo da lista de assinantes.

    É importante dizer que eu não testei isso a fundo. Apenas dei uma olhada superficial no Reflector. De qualquer forma, espero que ajude.


    http://www.israelaece.com
    terça-feira, 20 de julho de 2010 23:05
    Moderador