Como eu comentei neste outro artigo, podemos utilizar no WCF um recurso chamado streaming, que é uma alternativa interessante quando precisamos enviar grandes quantidades de informações, que nestes cenários, o mais comum é o envio ou o recebimento de arquivos. Para que tudo isso funcione, precisamos nos atentar a efetuar algumas configurações no WCF com relação as cotas e timeouts, que impõem limites durante o tráfego das informações.
Em princípio, esses são os únicos cuidados que devemos ter. Poderemos começar a ter outros problemas, se esse serviço for hospedado no IIS. Para que fosse possível hospedar um serviço WCF no IIS, a Microsoft utilizou a estrutura do pipeline do ASP.NET para receber e desviar a requisição para serviços WCF para o seu respectivo handler. Antes de qualquer análise das cotas que configuramos para o serviço, há um detalhe importante que devemos nos preocupar. Trata-se da propriedade MaxRequestLength da classe HttpRuntime, que determina a quantidade máxima (em KBytes) de conteúdo que uma requisição do ASP.NET poderá receber, onde o seu valor padrão é 4 MB. Essa propriedade influencia quando queremos efetuar o upload de um arquivo grande através de uma aplicação ASP.NET.
Como a requisição chega para o IIS, que por sua vez delega o processamento para a estrutura do ASP.NET, o mesmo valida o tamanho deste conteúdo, e se for maior do que o valor estipulado nesta propriedade, você receberá uma exceção do tipo HttpException, com a seguinte mensagem: Maximum request length exceeded. É algo até complicado de se diagnosticar, já que essa exceção não é propagada para o cliente que consome o serviço, e o tracing do WCF neste caso, ajudará a desvendar este problema. De qualquer forma, quando for hospedar um serviço WCF no IIS, é importante que você sincronize as cotas com o atributo maxRequestLength exposto pelo elemento httpRuntime, assim como podemos notar no exemplo abaixo, que está configurado para receber um arquivo de até 100 MB:
<?xml version=”1.0″?>
<configuration>
<system.web>
<httpRuntime maxRequestLength=”102400″/>
</system.web>
<system.serviceModel>
<services>
<service name=”Service”>
<endpoint address=””
binding=”basicHttpBinding”
contract=”IService”
bindingConfiguration=”config” />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name=”config”
messageEncoding=”Mtom”
transferMode=”Streamed”
maxBufferSize=”104857600″
maxBufferPoolSize=”104857600″
maxReceivedMessageSize=”104857600″>
</binding>
</basicHttpBinding>
</bindings>
</configuration>
Boas Francis,
Pode ser que sim, já que seu processo finaliza de forma brusca, não há tempo para ele conseguir informar o serviço de que algo ocorreu.
Mas você poderia colocar a regra no serviço, ou seja, quando você tentar invocar o callback, e o cliente não estiver não online, você pode removê-lo da lista de assinantes.
Olá Aece, seus artigos sobre WCF são muito bons! Meus Parabéns!
Faz um tempinho que venho procurando uma solução para um problema que estou tendo com WCF e nem mesmo encontrei em seus artigos sobre WCF.
O problema é o seguinte, crio um host e conecto varios clientes wcf ao mesmo, contudo quando eu forço o encerramento da aplicacao cliente sem a mesma avisar que foi fechada, por exemplo utilizando o CTRL+ALT+DEL, o HOST nao consegui capturar um evento que indique (cliente conctou ou cliente desconectou), sem a necessidade do cliente ter que fazer uma chamada de uma rotina para avisar que ele conectou ou desconectou, dessa forma eu não consigo saber se um cliente desconectou forcadamente e com isso nao o tiro da lista de cliente conectados, lembrando que, implementar callback nesse caso nao resolve.
Boas Francis,
Veja se isso pode te ajudar em algo: http://www.israelaece.com/post/Dectetando-a-desconexao.aspx
Eu ja havia feito exatamente como informa nesse seu post que esta me indicando. mas infelizmente continua nao funcionando, o problema é que quando voce da um Kill no processo cliente o evento que eu assinei do lado do servidor nao é disparado ( Fault e Closed ) todos sao assinados no construtor, isso é crucial para mim, pois eu saberia exatamente quando uma conexao foi fechado com isso retiraria o cliente da lista de conectados.
Olá, Israel.
Esse post solucionou meu problema.
Porém, lendo os detalhes do MaxRequestLenght em:
http://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.maxrequestlength.aspx, vi o seguinte:
[quote]"The MaxRequestLength property specifies the limit for the buffering threshold of the input stream. For example, this limit can be used to prevent denial of service attacks that are caused by users who post large files to the server. "[/quote]
[b]Há algum modo de proteger a aplicação de DoS, mesmo com o valor dessa propriedade alterado?[/b]
Sim, Israel foi esse post mesmo que esta me indicando que disse que nao resolveu meu problema (http://www.israelaece.com/post/Dectetando-a-desconexao.aspx).
Faça voce mesmo um teste, crie um Host e o Client, conecte os 2 clientes no host, e tente capturar o evento de (closed ou Faulted) mantando o processo de um dos clients. Notara que nenhum envento e disparado do lado do servidor indicando que esse processo que voce matou do cliente ja nao esta mais conectado.
Pois é Israel, isso que eu gostaria de evitar, pois assim dependeria de uma certa verificação para retira-los da lista, gostaria muito de evitar isso, que por sinal ja implementei e nao gosto dessa saida. O interessante mesmo era como eu faço com o socket conheco exatamente cada cliente conectado e no exato momento que perco a comunicação com o cliente devido a qualquer falha. Estou procurando na internet, vejo muita gente com o mesmo problema, encontro muito mais gringo com esse questionamento, mas até agora ninguem deu uma solução definitiva, eu continuo tentando resolver.
Boas Francis,
Já tentou utilizar o IInputSessionShutdown?