Quantcast
Channel: Windows Communication Foundation – Fernando Henrique Ferreira
Viewing all articles
Browse latest Browse all 7

Controle de instâncias entre requisições de serviços WCF

$
0
0

O WCF provê três modelos diferente de controle de instâncias, sendo estes modelos:

Per call instance mode – Uma nova instância do serviço WCF é criada para cada chamada de método invocada por um cliente e destruida após a resposta ser enviada.

Per session instance mode – Apenas uma instância de um serviço é criada para um conjunto de integrações com o cliente. A instância do serviço só é destruída quando o cliente termina suas requisições.

Single instance mode – Uma instância global do serviço é criada, e desta forma fica responsável por receber e processar todas as requisições de todos os clientes.

A enumeração InstanceContextMode é utilizada para indicar qual modelo de instâncias será utilizado pelo serviço durante o seu funcionamento. Ela determina qual associação deve existir entre o canal e o serviço.

Mas, para manter a instância de um serviço ativa, apenas alterar o modo de controle de instâncias não é suficiente. Para associar um cliente com uma instância particular do WCF, é preciso que o WCF consiga identificar o cliente que fez o invoque do método. Um modo de fazer isso é utilizar uma transport-level session, isto é, uma conexão contínua, tais como as mantidas pelos protocolos TCP e IPC.

Desta maneira, para mantermos uma sessão ativa entre o cliente e o serviço WCF, é preciso usar um binding como NetTcpBinding ou NetNamedPipeBinding. O WsHttpBinding também pode ser utilizado, pois ele é capaz de emular uma transport-level session, pois utiliza um ID de sessão no cabeçalho das mensagens, para identificar exclusivamente cada cliente. Em contrapartida, o BasicHttpBinding não pode ser utilizado, pois ele recria uma conexão sempre, o que impede a identificação do cliente pelo serviço WCF.

Neste post demonstro um exemplo de como manter a instância de um serviço durante múltiplas chamadas de método para um cliente. Neste exemplo configurei o serviço para utilizar WsHttpBinding. Os blocos necessários para implementação do serviço estão distribuídos a seguir.

Configuração do WsHttpBinding

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="NewBehavior">
          <serviceDebug />
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="NewBehavior" name="WcfHostService.StatusService">
        <endpoint address="" binding="wsHttpBinding" contract="WcfHostService.IStatusService">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>

Código do Serviço

    [DataContract]
    public enum Status {

        [EnumMember]
        Stopped = 1,
        [EnumMember]
        Initializing = 2,
        [EnumMember]
        Processing = 3,
        [EnumMember]
        Ready = 4
    }

    [ServiceContract]
    public interface IStatusService {

        [OperationContract]
        void ChangeStatus(Status newStatus);

        [OperationContract]
        Status GetCurrentStatus();

        [OperationContract]
        int GetNumberOfInteractions();
    }

    [ServiceKnownType(typeof(Status))]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class StatusService : IStatusService {

        private Status _currentStatus;
        private int _interactions;

        public StatusService() {

            this._currentStatus = Status.Stopped;
            this._interactions = 0;
        }

        public void ChangeStatus(Status newStatus) {

            this._interactions++;
            this._currentStatus = newStatus;
        }

        public int GetNumberOfInteractions() {

            return this._interactions;
        }

        public Status GetCurrentStatus() {

            return this._currentStatus;
        }
    }

Código da Camada Cliente

    static void Main(string[] args) {

        int interactions = 0;
        var client = new StatusService.StatusServiceClient();

        // Change status to Initializing
        client.ChangeStatus(StatusService.Status.Initializing);
        interactions  = client.GetNumberOfInteractions();
        Console.WriteLine("Current status is: " + client.GetCurrentStatus());
        Console.WriteLine("Interaction number: " + interactions);

        // Change status to Processing
        client.ChangeStatus(StatusService.Status.Processing);
        interactions = client.GetNumberOfInteractions();            
        Console.WriteLine("Current status is: " + client.GetCurrentStatus());
        Console.WriteLine("Interaction number: " + interactions);
            
        // Change status to Ready
        client.ChangeStatus(StatusService.Status.Ready);
        interactions = client.GetNumberOfInteractions();
        Console.WriteLine("Current status is: " + client.GetCurrentStatus());
        Console.WriteLine("Interaction number: " + interactions);
    }

Por

MSc. Fernando Henrique Inocêncio Borba Ferreira.

Microsoft Most Valuable Professional – Visual C#

 

Referências:

http://www.codeproject.com/Articles/86007/3-ways-to-do-WCF-instance-management-Per-call-Per

http://msdn.microsoft.com/pt-br/library/system.servicemodel.instancecontextmode.aspx

http://msdn.microsoft.com/pt-br/library/ms752230.aspx

http://my.safaribooksonline.com/book/programming/microsoft-wcf/0596526997/instance-management/orm9780596526993-chp-4-sect-3

http://msdn.microsoft.com/en-us/library/ff650619.aspx



Viewing all articles
Browse latest Browse all 7

Trending Articles