Compartilhar via


Codificadores personalizados

Este tópico discute como criar codificadores personalizados.

No WCF (Windows Communication Foundation), você usa um binding para especificar como transferir dados em uma rede entre endereços. Uma associação é composta por uma sequência de elementos de associação. Uma associação inclui elementos de associação de protocolo opcionais, 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 Mensagens) e Texto.

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

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. Os codificadores (por exemplo, Text Xml) apenas codificam a mensagem.

Ao se conectar a um cliente ou servidor pré-existente, 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 atende a todo o público-alvo do seu serviço, considere disponibilizar seu serviço em múltiplos endpoints. 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 codificadores de mensagens diferentes com outros elementos de associação.

Codificadores System-Provided

O WCF fornece várias associações fornecidas pelo sistema que são 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 incluídos no WCF, ou criar seu próprio codificador personalizado. O codificador de mensagem de texto dá suporte a 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 ("XML Antigo Simples") 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 Escolhendo um Transporte.

Como trabalhar com codificadores de System-Provided

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

O WCF fornece os seguintes tipos de elementos de vínculo derivados da classe MessageEncodingBindingElement que podem fornecer codificação de texto, binária e por Mecanismo de Otimização de Transmissão de Mensagens (MTOM):

  • TextMessageEncodingBindingElement: o codificador mais interoperável, mas 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 usados para mensagens XML baseadas em binário. Isso é a mais eficiente das opções de codificação, mas a menos interoperável delas, pois só tem suporte de endpoints do WCF.

  • MtomMessageEncodingBindingElement: representa o elemento de associação que especifica a codificação de caracteres e o controle de versão de 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 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 as-is, sem conversão em texto.

O elemento de associação cria um binário, MTOM ou texto MessageEncoderFactory. 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 para cada sessão. O codificador binário usa isso para coordenar dicionários dinâmicos (consulte Infraestrutura XML).

Os métodos ReadMessage e WriteMessage são o núcleo dos codificadores. Os métodos permitem a leitura de uma mensagem de um fluxo ou de uma Byte matriz. Matrizes de bytes são usadas quando o transporte está funcionando no modo bufferizado. As mensagens são sempre gravadas em fluxos. Se o transporte precisar armazenar a mensagem em buffer, ele fornecerá um fluxo que realiza 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 ela ou para determinar se a mensagem de saída é válida para esse codificador.

Cada uma das três implementações de 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á uma série de recursos fornecidos pelos codificadores fornecidos pelo sistema.

Pool

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

As instâncias XmlDictionaryReader e XmlDictionaryWriter são compartilhadas 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 interno AddSessionInformationToMessage . Ele adiciona as cadeias de caracteres como UTF-8 no início da mensagem, prefixando-as com o comprimento delas. O cabeçalho inteiro do dicionário é prefixado com o comprimento de seus dados. A operação inversa é executada por um método interno ExtractSessionInformationFromMessage .

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 interna MessagePatterns 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 MessageHeaders objeto sem analisar o XML. Caso contrário, ele volta para o método padrão.

Codificação MTOM

A MtomMessageEncodingBindingElement classe tem uma propriedade de configuração adicional chamada MaxBufferSize. Isso coloca um limite superior na quantidade de dados que ele tem permissão para 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 do 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 blocos de dados binários, ou "BLOBs" (Objetos Grandes Binários), sem convertê-los para a 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 MessageEncoder classe, que serve como uma fábrica 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 fábrica que crie 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 mensagem personalizado: codificador de texto personalizado e codificador de mensagem personalizado: codificador de compactação.

Consulte também