Atualizações de fluxo personalizadas

Os transportes orientados a fluxo, como TCP e Pipes Nomeados, operam em um fluxo contínuo de bytes entre o cliente e o servidor. Esse fluxo é realizado por um objeto Stream. Em uma atualização de fluxo, o cliente deseja adicionar uma camada de protocolo opcional à pilha de canais e solicita que a outra extremidade do canal de comunicação faça isso. A atualização do fluxo consiste em substituir o objeto original Stream por um atualizado.

Por exemplo, você pode criar um fluxo de compactação diretamente sobre o fluxo de transporte. Nesse caso, o transporte Stream original é substituído por um que encapsula a compactação Stream em torno do original.

Você pode aplicar várias atualizações de fluxo, cada uma encapsulando a anterior.

Como funcionam as atualizações de fluxo

Há quatro componentes no processo de atualização de fluxo.

  1. Um Iniciador de fluxo de atualização inicia o processo: no tempo de execução, ele pode iniciar uma solicitação para a outra extremidade de sua conexão para atualizar a camada de transporte do canal.

  2. Um Aceitor de fluxo de atualização realiza a atualização: em tempo de execução, ele recebe a solicitação de atualização do outro computador e, se possível, aceita a atualização.

  3. Um Provedor de atualização cria o Iniciador no cliente e no Aceitor no servidor.

  4. Um Elemento de associação de atualização de fluxo é adicionado às associações no serviço e no cliente e cria o provedor no tempo de execução.

Observe que, no caso de várias atualizações, o Iniciador e o Aceitor encapsulam computadores de estado para impor quais transições de atualização são válidas para cada Iniciação.

Como implementar uma atualização de fluxo

O WCF (Windows Communication Foundation) fornece quatro classes abstract que você pode implementar:

Para implementar uma atualização de fluxo personalizada, faça o seguinte. Este procedimento implementa um processo mínimo de atualização de fluxo nos computadores cliente e servidor.

  1. Crie uma classe que implementa StreamUpgradeInitiator.

    1. Substitua o método InitiateUpgrade que será usado no fluxo a ser atualizado e retorne o fluxo atualizado. Esse método funciona de forma síncrona; há métodos análogos para iniciar a atualização de forma assíncrona.

    2. Substitua o método GetNextUpgrade para verificar se há atualizações adicionais.

  2. Crie uma classe que implementa StreamUpgradeAcceptor.

    1. Substitua o método AcceptUpgrade que será usado no fluxo a ser atualizado e retorne o fluxo atualizado. Esse método funciona de modo síncrono; há métodos análogos para aceitar a atualização de maneira assíncrona.

    2. Substitua o método CanUpgrade para determinar se a atualização solicitada é compatível com esse aceitor de atualização neste momento no processo de atualização.

  3. Crie uma classe que implementa StreamUpgradeProvider. Substitua os métodos CreateUpgradeAcceptor e CreateUpgradeInitiator para retornar instâncias do aceitor e do iniciador definidos nas etapas 2 e 1.

  4. Crie uma classe que implementa StreamUpgradeBindingElement.

    1. Substitua o método BuildClientStreamUpgradeProvider no cliente e o método BuildServerStreamUpgradeProvider no serviço.

    2. Substitua o método BuildChannelFactory no cliente e o método BuildChannelListener no serviço para adicionar o Elemento de associação de atualização a BindingParameters.

  5. Adicione o novo elemento de associação de atualização de fluxo às associações no servidor e nos computadores cliente.

Atualizações de segurança

A adição de uma atualização de segurança é uma versão especializada do processo geral de atualização do fluxo.

O WCF já fornece dois elementos de associação para atualizar a segurança do fluxo. A configuração de segurança no nível do transporte é encapsulada por WindowsStreamSecurityBindingElement e SslStreamSecurityBindingElement, o que pode ser configurado e adicionado a uma associação personalizada. Esses elementos de associação estendem a classe StreamUpgradeBindingElement que cria os provedores de atualização de fluxo de cliente e servidor. Esses elementos de associação têm métodos que criam as classes de provedor de atualização de fluxo de segurança especializadas, que não são public, portanto, para esses dois casos, tudo o que você precisa fazer é adicionar o elemento de associação à associação.

Para cenários de segurança não atendidos pelos dois elementos de associação acima, três classes abstract relacionadas à segurança são derivadas das classes base de inicialização, aceitador e provedor acima:

  1. System.ServiceModel.Channels.StreamSecurityUpgradeInitiator

  2. System.ServiceModel.Channels.StreamSecurityUpgradeAcceptor

  3. System.ServiceModel.Channels.StreamSecurityUpgradeProvider

O processo de implementação de uma atualização de fluxo de segurança é o mesmo de antes, com a diferença que você derivaria dessas três classes. Substitua as propriedades adicionais nessas classes para fornecer informações de segurança para o runtime.

Várias atualizações

Para criar solicitações de atualização adicionais, repita o processo acima: crie extensões adicionais e elementos de associação StreamUpgradeProvider. Adicione os elementos de associação à associação. Os elementos de associação adicionais são processados sequencialmente, começando com o primeiro elemento de associação adicionado à associação. Em BuildChannelFactory e BuildChannelListener, cada provedor de atualização pode determinar como colocar a própria camada em qualquer parâmetro de associação de atualização pré-existente. Em seguida, ele deve substituir o parâmetro de associação de atualização existente por um novo parâmetro de associação de atualização composta.

Como alternativa, um provedor de atualização pode dar suporte a várias atualizações. Por exemplo, talvez você queira implementar um provedor de atualização de fluxo personalizado que dê suporte à segurança e à compactação. Execute as seguintes etapas:

  1. Faça a subclasse de StreamSecurityUpgradeProvider para gravar a classe de provedor que cria o Iniciador e o Aceitor.

  2. Fazer a subclasse de StreamSecurityUpgradeInitiator, verificando a substituição do método GetNextUpgrade para retornar os tipos de conteúdo para o fluxo de compactação e o fluxo seguro em ordem.

  3. Faça a subclasse de StreamSecurityUpgradeAcceptor, o que entende os tipos de conteúdo personalizados em seu método CanUpgrade.

  4. O fluxo será atualizado após cada chamada para GetNextUpgrade e CanUpgrade.

Confira também