As cotas do WCF são mecanismos que utilizamos para evitar o consumo excessivo de recursos que a infraestrutura do WCF utiliza para efetuar a comunicação. Quando bem configuradas, elas evitam que eventuais ataques (DoS) sejam realizados ao teu serviço, que pode prejudicar toda a sua infraestrutura. E, assim como os timeouts, os limites de tamanho e cotas são totalmente configuráveis.
Essas configurações já vem com um valor padrão definido, e que você deve ajustar de acordo com a sua necessidade. Como grande parte dessas configurações são determinadas com números inteiros, e muitas pessoas (talvez para efeito de testes) colocam o valor máximo permitido (int.MaxValue). Provavelmente isso evitará possíveis erros que estejam ocorrendo durante os testes, mas se não se preocupar em ajustá-los de acordo com o volume que o teu serviço trabalha, você não evitará possíveis ataques.
Essas configurações são características específicas de um binding, e que podem ser realizadas de forma declarativa ou imperativa. Abaixo consta a relação dessas configurações (limites e cotas) que são comuns para todos os bindings:
-
maxBufferPoolSize (65.536): Determina, em bytes, a quantidade máxima de memória que será alocada para o processamento da mensagem.
-
maxBufferSize (65.536): Número inteiro que representa a quantidade de bytes do buffer que será usado para armazenar uma mensagem na memória.
-
maxReceivedMessageSize (65.536): Como o próprio nome diz, recebe um número inteiro que corresponde ao tamanho máximo (em bytes) da mensagem que ele (cliente ou serviço) pode receber.
-
readerQuotas: Define alguns critérios para o processamento das mensagens SOAP (XML).
-
maxDepth (32): Um número inteiro que determina a profundidade do aninhamento dos elementos (tipos). Por exemplo, você tem uma classe que possui uma propriedade de outro tipo; essa propriedade representa outro tipo, e assim por diante. Isso será transformado Xml e, consequentemente, a estrutura será representada de forma hierárquica.
-
maxStringContentLength (8.192): O tamanho máximo de uma string que será permitida. Se você tiver strings muito largas, então você precisa alterar esse parâmetro.
-
maxArrayLength (16.384): Um número inteiro que especifica a quantidade máxima de elementos que podemos ter dentro de arrays. Há situações onde o teu serviço te retorna/recebe um array, e se a quantidade de elementos dele for maior do que o valor especificado neste atributo, uma exceção será disparada.
-
maxBytesPerRead (4.096): Define a quantidade de bytes permitida para cada leitura de cada elemento do XML.
-
maxNameTableCharCount (16.384): Quantidade máxima de caracteres permitidas na TableName (XmlDictionaryReader). Todos os nomes dos elementos e atributos retornados são catalogados dentro de uma NameTable. Quando o mesmo nome é retornado várias vezes, a mesma instância da classe string será retornada, tornando o processamento mais eficiente.
-
Observação: Os valores que estão entre parenteses, são os valores padrão.
Atente-se para estas propriedades. Elas não são publicadas no documento WSDL e, consequentemente, não são automaticamente propagadas para o cliente. Ao fazer a referência de um serviço em uma aplicação cliente, os valores que você visualiza no arquivo de configuração são apenas os valores padrão de cada propriedade. Compete a você alterar para ajustar de acordo com a sua necessidade. Se elas não estiverem sincronizadas ou até com os valores bem dimensionados, dificilmente você conseguirá efetuar a comunicação com sucesso.
Boas Galera,
Limites no tamanho das mensagens é algo que me encomoda muito e queria saber mais informaçoes sobre seus propositos e melhores praticas.
Seguinte, trabalho com servicos que demandam alta quantidade de informaçoes para B2B usando WCF, por ex.: eu preciso que um distribuidor meu receba todos os meus produtos em estoque atualmente, sabendo que eu tenho mais de 20.000 produtos com inumeros campos, se eu mandar isso via WCF vai me dar um erro de limite de tamanho. Entao, aumentar o limite nao acho que seria o mais recomendado na minha opniao pois voce estaria criando uma mensagem gigantesca a nivel de web para enviar toda essa informaçao correndo o risco de um pique no meio da transferencia e ter q reiniciar tudo novamente qdo a conexao for restabelecida dentre muitas outras situaçoes que eu vejo que uma mensagem grande não seria o ideal.
O que eu acho que fosse o correto e talvez seja possivel, apesar de ainda estar estudando o WCf é que voce fizesse uma requisao de um grande volume de informaçoes mas que essas informaçoes viessem em pacotes menores e juntasse no cliente, assim nao seria necessario mexer no tamanho limite da mensagem, desde que viesse varias mensagens em sequencia e iriam somando-se no cliente, mas de forma que eu pudesse ir visualizando essas informaçoes a medida que fossem chegando para evitar que o cliente percebesse que ainda tem informaçoes chegando.
Se existir uma maneira de fazer isso, eu gostaria muito de um sample e uma explicaçao de seu uso pois trabalho sim com um fluxos grandes de informaçoes, como uma tabela inteira de produto sendo trafegada via WCF.
Atenciosamente,
Alexsandro Nunes Lacerda
http://www.alexsandronunes.com.br
——————————-
Microsoft MCP e MCTS
Boas Alexsandro,
No WCF já temos uma funcionalidade semelhante, que é a possibilidade de enviar/retornar Streams. Com ele, ao invés da mensagem ser totalmente "bufferizada", de pacotes em pacotes, o resultado já vai sendo enviado ao cliente.
Esta funcionalidade tem duas características que talvez inviabilize a sua utilização: você não pode utilizar coisas como mensagens confiáveis ou segurança em nível de mensagem, pois elas dependem da mensagem inteira para efetuar a validação, algo que não acontece quando se utiliza Streams (O Chunking Channel (http://msdn.microsoft.com/en-us/library/aa717050.aspx) resolve este problema). A segunda característica é que os parâmetros (de entrada e retorno dos métodos) devem ser do tipo System.IO.Stream. Só que isso é legal quando você está transferindo arquivos de um lado ao outro; quando temos objetos, apesar de você conseguir serializá-los, não fica muito intuitivo.
O que geralmente tenho adotado, é a possibilidade de criar contratos que suportem paginação de resultados. Como muitas vezes, meus serviços que afetam o comportamento da minha estrutura, são separados daqueles que fornecem dados para relatórios (CQS), não vejo problema em ter nestes serviços, características que são direcionadas para UI.
Independentemente do modelo escolhido, um ponto importante a ser considerado é a capacidade de compressão. Nativamente o WCF não dá suporte à isso, mas quando o serviço é hospedado no IIS, você pode tirar proveito da compressão dinâmica que o IIS fornece e, consequentemente, todas as respostas serão enviadas ao cliente comprimidas.
Boas as suas dicas!
Comecei a estudar hoje cedo sobre WCF Data Service e queria saber se eu teria o mesmo problema com o tamanho da mensagem se eu usar este tipo de WCF.
Boas Alexsandro,
Eu não olhei o WCF Data Services, mas por ele estar construído em cima do WCF, provavelmente (e felizmente) ele terá as restrições que você encontrou.