Compartilhar via


Decodificadores personalizados

Este tópico discute como criar codificadores personalizados.

No WCF (Windows Communication Foundation), você usa uma associação para especificar como transferir dados em uma rede entre pontos de extremidade. Uma associação é composta por uma sequência de elementos de associação. Uma associação inclui elementos opcionais de associação de protocolo, como segurança, um elemento de associação de Codificador de mensagem necessário e um elemento de associação de transporte necessário. Um codificador de mensagem é representado por um elemento de associação de codificação de mensagem. Três codificadores de mensagem estão incluídos no WCF: Binário, MTOM (Mecanismo de otimização de transmissão de mensagem) e Texto.

Um elemento de associação de codificação de mensagem serializa uma saída Message e a passa para o transporte ou recebe a forma serializada de uma mensagem do transporte e a passa para a camada de protocolo, se presente, ou para o aplicativo, se não estiver presente.

Codificadores de mensagens transformam instâncias Message de e para uma representação de fio. Embora os codificadores sejam descritos como sentados acima da camada de transporte na pilha do canal, eles residem dentro da camada de transporte. Os transportes (por exemplo, HTTP) formatarão a mensagem de acordo com os requisitos do padrão de transporte. Codificadores (por exemplo, Text Xml) apenas codificam a mensagem.

Ao se conectar a um cliente ou servidor preexistente, talvez você não tenha escolha sobre como usar uma codificação de mensagem específica. No entanto, os serviços do WCF podem ser acessíveis por meio de vários pontos de extremidade, cada um com um transporte diferente. Quando um único codificador não abrange todo o público-alvo do serviço, considere expor seu serviço em vários pontos de extremidade. Em seguida, os aplicativos cliente podem escolher o ponto de extremidade que é melhor para eles. O uso de vários pontos de extremidade permite combinar as vantagens de diferentes codificadores de mensagens com outros elementos de associação.

Codificadores fornecidos pelo sistema

O WCF fornece várias associações fornecidas pelo sistema projetadas para abranger os cenários de aplicativo mais comuns. Cada uma dessas associações combina um transporte, um codificador de mensagens e outras opções (segurança, por exemplo). Este tópico descreve como estender os codificadores de mensagem Text, Binary e MTOM que estão incluídos no WCF ou criar seu próprio codificador personalizado. O codificador de mensagem de texto dá suporte a uma codificação XML simples, bem como codificações SOAP. O modo de codificação XML simples do codificador de mensagem de texto é chamado de codificador POX ("Plain Old XML") para distingui-lo da codificação SOAP baseada em texto.

Para obter mais informações sobre as combinações de elementos de associação fornecidas pelas associações fornecidas pelo sistema, consulte a seção correspondente em Escolher um transporte.

Como trabalhar com codificadores fornecidos pelo sistema

Uma codificação é adicionada a uma associação usando uma classe derivada de MessageEncodingBindingElement.

O WCF fornece os seguintes tipos de elementos de associação derivados da classe MessageEncodingBindingElement que podem fornecer codificação de texto, binário e MTOM (Mecanismo de otimização de transmissão de mensagens):

  • TextMessageEncodingBindingElement: o codificador mais interoperável, mas o codificador menos eficiente para mensagens XML. Um serviço Web ou cliente de serviço Web geralmente pode entender XML textual. No entanto, a transmissão de grandes blocos de dados binários como texto não é eficiente.

  • BinaryMessageEncodingBindingElement: representa o elemento de associação que especifica a codificação de caracteres e o controle de versão de mensagem usado para mensagens XML baseadas em binário. Isso é mais eficiente das opções de codificação, mas a menos interoperável, pois só tem suporte de pontos de extremidade do WCF.

  • MtomMessageEncodingBindingElement: representa o elemento de associação que especifica a codificação de caracteres e o controle de versão da mensagem usados para uma mensagem usando uma codificação MTOM (Mecanismo de otimização de transmissão de mensagens). O MTOM é uma tecnologia eficiente para transmitir dados binários em mensagens do WCF. O codificador MTOM tenta equilibrar entre eficiência e interoperabilidade. A codificação MTOM transmite a maioria dos XML na forma textual, mas otimiza grandes blocos de dados binários transmitindo-os como estão, sem conversão em texto.

O elemento de associação cria um MessageEncoderFactory binário, de MTOM ou de texto. O alocador cria uma instância MessageEncoderFactory binária, de MTOM ou de texto. Normalmente, há apenas uma única instância. No entanto, se as sessões forem usadas, um codificador diferente poderá ser fornecido a cada sessão. O codificador binário usa isso para coordenar dicionários dinâmicos (consulte Infraestrutura de XML).

Os métodos ReadMessage e WriteMessage são o núcleo dos codificadores. Os métodos fornecem a leitura de uma mensagem de um fluxo ou de uma matriz Byte. As matrizes de bytes são usadas quando o transporte está operando no modo em buffer. As mensagens são sempre gravadas em fluxos. Se o transporte precisar armazenar a mensagem em buffer, ele fornecerá um fluxo que faz o armazenamento em buffer.

O restante dos membros trabalha com conteúdo de suporte, tipos de mídia e MessageVersion. O transporte chama esses métodos de codificador para testar se a mensagem de entrada pode ser decodificada por ele ou para determinar se a mensagem de saída é válida para esse codificador.

Cada uma das três implementações do codificador adiciona propriedades que são relevantes para as codificações específicas e são totalmente configuráveis. Os codificadores também expõem cotas de leitor que têm padrões seguros. Consulte a Infraestrutura XML para uma discussão sobre as cotas.

Recursos de codificadores fornecidos pelo sistema

Há vários recursos fornecidos pelos codificadores fornecidos pelo sistema.

Agrupamento

Cada uma das implementações do codificador tenta agrupar o máximo possível. Reduzir alocações é uma maneira fundamental de melhorar o desempenho do código gerenciado. Para realizar esse armazenamento em pool, as implementações usam a classe SynchronizedPool. O arquivo C# contém uma descrição das otimizações adicionais usadas por essa classe.

As instâncias XmlDictionaryReader e XmlDictionaryWriter são agrupadas e reinicializadas para impedir a alocação de novas para cada mensagem. Para os leitores, um retorno de chamada OnClose recupera o leitor quando Close() é chamado. O codificador também recicla alguns objetos de estado de mensagem usados ao construir mensagens. Os tamanhos desses pools são configuráveis pelas propriedades MaxReadPoolSize e MaxWritePoolSize em cada uma das três classes derivadas de MessageEncodingBindingElement.

Codificação binária

Quando a codificação binária usa sessões, a cadeia de caracteres de dicionário dinâmico deve ser comunicada ao receptor da mensagem. Isso é feito prefixando a mensagem com as cadeias de caracteres de dicionário dinâmico. O receptor remove as cadeias de caracteres, adiciona-as à sessão e processa a mensagem. Passar corretamente cadeias de caracteres de dicionário requer que o transporte seja armazenado em buffer.

As cadeias de caracteres são acrescentadas à mensagem por um método AddSessionInformationToMessage interno. Ele adiciona as cadeias de caracteres como UTF-8 à frente da mensagem prefixada com seu comprimento. O cabeçalho inteiro do dicionário é prefixado com o comprimento de seus dados. A operação inversa é executada por um método ExtractSessionInformationFromMessage interno.

Além de processar chaves de dicionário dinâmicas, as mensagens em buffer com sessão são recebidas de maneira exclusiva. Em vez de criar um leitor sobre o documento e processá-lo, o codificador binário usa a classe MessagePatterns interna para desconstruir o fluxo binário. A ideia é que a maioria das mensagens tenha um determinado conjunto de cabeçalhos que aparecem em uma determinada ordem quando gerados pelo WCF. O sistema de padrões separa a mensagem com base no que ela espera. Se for bem-sucedido, ele inicializará um objeto MessageHeaders sem analisar o XML. Caso contrário, ele retornará ao método padrão.

Codificação de MTOM

A classe MtomMessageEncodingBindingElement tem uma propriedade de configuração adicional chamada MaxBufferSize. Isso coloca um limite superior na quantidade de dados que ele pode armazenar em buffer durante o processo de leitura de uma mensagem. O Infoset (Conjunto de informações XML), ou outras partes MIME, talvez precise ser armazenado em buffer para remontar todas as partes MIME em uma única mensagem.

Para trabalhar corretamente com HTTP, a classe de codificador de mensagens MTOM interna fornece algumas APIs internas para GetContentType(que também é interna) e WriteMessage, que é pública e pode ser substituída. Mais comunicação deve ocorrer para garantir que os valores nos cabeçalhos HTTP concordem com valores nos cabeçalhos MIME.

Internamente, o codificador de mensagens MTOM usa leitores de texto do WCF e é semelhante ao codificador de texto. A principal diferença é que ele otimiza grandes partes de binário ou "Objetos Binários Grandes" (BLOBs), não os convertendo em codificação Base-64 antes de serem inseridos nos bytes da mensagem. Em vez disso, esses BLOBs são mantidos extraídos e referenciados como anexos MIME.

Escrevendo seu próprio codificador

Para implementar seu próprio codificador de mensagens personalizado, você deve fornecer implementações personalizadas das seguintes classes base abstratas:

A conversão da representação na memória de uma mensagem em uma representação que pode ser gravada em um fluxo é encapsulada dentro da classe MessageEncoder, que serve como um alocador para leitores XML e gravadores XML que dão suporte a tipos específicos de codificações XML.

É o código que você escreve nesses métodos que manipula a conversão entre o protocolo de transporte padrão e a codificação personalizada.

Em seguida, você precisa codificar uma classe de alocador que cria seu codificador personalizado. Substitua Encoder para retornar uma instância do seu MessageEncoder personalizado.

Em seguida, conecte o MessageEncoderFactory personalizado à pilha de elementos de associação usada para configurar o serviço ou o cliente substituindo o método CreateMessageEncoderFactory para retornar uma instância dessa alocador.

Há dois exemplos fornecidos com o WCF que ilustram esse processo com o código de exemplo: Codificador de mensagens personalizadas: codificador de texto personalizado e Codificador de mensagens personalizadas: codificador de compactação.

Confira também