Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O exemplo HttpCookieSession demonstra como criar um canal de protocolo personalizado para usar cookies HTTP para gerenciamento de sessão. Esse canal permite a comunicação entre os serviços do Windows Communication Foundation (WCF) e clientes ASMX ou entre clientes WCF e serviços ASMX.
Quando um cliente chama um método Web em um serviço Web ASMX baseado em sessão, o mecanismo de ASP.NET faz o seguinte:
Gera uma ID exclusiva (ID da sessão).
Gera o objeto de sessão e o associa à ID exclusiva.
Adiciona a ID exclusiva a um cabeçalho de resposta HTTP Set-Cookie e a envia ao cliente.
Identifica o cliente em chamadas subsequentes com base na ID da sessão que ele envia para ele.
O cliente inclui essa ID de sessão em suas solicitações subsequentes para o servidor. O servidor usa a ID da sessão do cliente para carregar o objeto de sessão apropriado para o contexto HTTP atual.
Padrão de Troca de Mensagens do Canal HttpCookieSession
Este exemplo permite sessões para cenários semelhantes a ASMX. Na parte inferior de nossa pilha de canais, temos o transporte HTTP que dá suporte a IRequestChannel e IReplyChannel. O trabalho do canal é fornecer sessões para os níveis mais altos da pilha de canais. O exemplo implementa dois canais, (IRequestSessionChannel e IReplySessionChannel) que dão suporte a sessões.
Canal de Serviço
O exemplo fornece um canal de serviço na HttpCookieReplySessionChannelListener classe. Esta classe implementa a interface IChannelListener e converte o canal IReplyChannel de posição inferior na pilha de canais em um IReplySessionChannel. Esse processo pode ser dividido nas seguintes partes:
Quando o ouvinte de canais é aberto, ele aceita um canal interno do ouvinte interno. Como o ouvinte interno é um ouvinte de datagrama e o tempo de vida de um canal aceito é dissociado do tempo de vida do ouvinte, podemos fechar o ouvinte interno e manter apenas o canal interno
this.innerChannelListener.Open(timeoutHelper.RemainingTime()); this.innerChannel = this.innerChannelListener.AcceptChannel(timeoutHelper.RemainingTime()); this.innerChannel.Open(timeoutHelper.RemainingTime()); this.innerChannelListener.Close(timeoutHelper.RemainingTime());Quando o processo aberto é concluído, configuramos um loop de mensagem para receber mensagens do canal interno.
IAsyncResult result = BeginInnerReceiveRequest(); if (result != null && result.CompletedSynchronously) { // do not block the user thread this.completeReceiveCallback ??= new WaitCallback(CompleteReceiveCallback); ThreadPool.QueueUserWorkItem(this.completeReceiveCallback, result); }Quando uma mensagem chega, o canal de serviço examina o identificador da sessão e faz a demultiplexação para o canal de sessão apropriado. O ouvinte de canais mantém um dicionário que mapeia os identificadores da sessão para as instâncias do canal de sessão.
Dictionary<string, IReplySessionChannel> channelMapping;
A HttpCookieReplySessionChannel classe implementa IReplySessionChannel. Níveis mais altos da pilha de canais chamam o método ReceiveRequest para ler as solicitações desta sessão. Cada canal de sessão tem uma fila de mensagens privada que é preenchida pelo canal de serviço.
InputQueue<RequestContext> requestQueue;
No caso de alguém chamar o ReceiveRequest método e não houver mensagens na fila de mensagens, o canal aguarda um período especificado antes de se desligar. Isso limpa os canais de sessão criados para clientes que não são do WCF.
Usamos o channelMapping para acompanhar o ReplySessionChannels, e não fechamos nossos canais subjacentes innerChannel até que todos os canais aceitos tenham sido fechados. Dessa forma HttpCookieReplySessionChannel pode existir além do tempo de vida de HttpCookieReplySessionChannelListener. Também não precisamos nos preocupar se o ouvinte receberá o lixo coletado abaixo de nós, pois os canais aceitos mantêm uma referência ao ouvinte por meio do retorno de chamada OnClosed.
Canal do cliente
O canal de cliente correspondente está na HttpCookieSessionChannelFactory classe. Durante a criação do canal, a fábrica de canais encapsula o canal de solicitação interna com um HttpCookieRequestSessionChannel. A HttpCookieRequestSessionChannel classe encaminha as chamadas para o canal de solicitação subjacente. Quando o cliente fecha o proxy, HttpCookieRequestSessionChannel envia uma mensagem para o serviço que indica que o canal está sendo fechado. Assim, a pilha de canais de serviço pode desligar normalmente o canal de sessão que está em uso.
Associação e Elemento de Associação
Depois de criar os canais de serviço e cliente, a próxima etapa é integrá-los ao runtime do WCF. Os canais são expostos ao WCF por meio das associações e dos elementos de associação. Uma associação consiste em um ou muitos elementos de associação. O WCF oferece várias associações definidas pelo sistema; por exemplo, BasicHttpBinding ou WSHttpBinding. A HttpCookieSessionBindingElement classe contém a implementação do elemento de associação. Ele substitui os métodos de criação do ouvinte de canais e da fábrica de canais, para fazer as instanciações necessárias do ouvinte de canais ou da fábrica de canais.
O exemplo usa asserções de política para a descrição do serviço. Isso permite que o exemplo publique seus requisitos de canal para outros clientes que podem consumir o serviço. Por exemplo, esse elemento de associação publica declarações de política para permitir que os possíveis clientes saibam que ele permite sessões. Como o exemplo habilita a ExchangeTerminateMessage propriedade na configuração do elemento de associação, ele adiciona as declarações necessárias para mostrar que o serviço dá suporte a uma ação de troca de mensagens extra para encerrar a conversa de sessão. Em seguida, os clientes podem usar essa ação. O código WSDL a seguir mostra as declarações de política criadas a partir do HttpCookieSessionBindingElement.
<wsp:Policy wsu:Id="HttpCookieSessionBinding_IWcfCookieSessionService_policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsp:ExactlyOne>
<wsp:All>
<wspe:Utf816FFFECharacterEncoding xmlns:wspe="http://schemas.xmlsoap.org/ws/2004/09/policy/encoding"/>
<mhsc:httpSessionCookie xmlns:mhsc="http://samples.microsoft.com/wcf/mhsc/policy"/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
A HttpCookieSessionBinding classe é uma associação fornecida pelo sistema que usa o elemento de associação descrito anteriormente.
Adicionando o canal ao sistema de configuração
O exemplo fornece duas classes que expõem o canal de exemplo por meio da configuração. A primeira é um BindingElementExtensionElement para o HttpCookieSessionBindingElement. A maior parte da implementação é delegada ao HttpCookieSessionBindingConfigurationElement, que deriva de StandardBindingElement.
HttpCookieSessionBindingConfigurationElement tem propriedades que correspondem às propriedades em HttpCookieSessionBindingElement.
Seção de Extensão do Elemento de Associação
A seção HttpCookieSessionBindingElementSection é uma BindingElementExtensionElement que expõe HttpCookieSessionBindingElement ao sistema de configuração. Com algumas substituições do nome da seção de configuração, o tipo do elemento de associação e como criar o elemento de associação são definidos. Em seguida, podemos registrar a seção de extensão em um arquivo de configuração da seguinte maneira:
<configuration>
<system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="httpCookieSession"
type=
"Microsoft.ServiceModel.Samples.HttpCookieSessionBindingElementElement,
HttpCookieSessionExtension, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null"/>
</bindingElementExtensions >
</extensions>
<bindings>
<customBinding>
<binding name="allowCookiesBinding">
<textMessageEncoding messageVersion="Soap11WSAddressing10" />
<httpCookieSession sessionTimeout="10" exchangeTerminateMessage="true" />
<httpTransport allowCookies="true" />
</binding>
</customBinding>
</bindings>
</system.serviceModel>
</configuration>
Código de Teste
O código de teste para usar esse transporte de exemplo está disponível nos diretórios Cliente e Serviço. Ele consiste em dois testes: um teste usa uma associação com allowCookies definido como true no cliente. O segundo teste permite o desligamento explícito (usando o encerramento da troca de mensagens) na associação.
Ao executar o exemplo, você deverá ver a seguinte saída:
Simple binding:
AddItem(10000,2): ItemCount=2
AddItem(10550,5): ItemCount=7
RemoveItem(10550,2): ItemCount=5
Items
10000, 2
10550, 3
Smart binding:
AddItem(10000,2): ItemCount=2
AddItem(10550,5): ItemCount=7
RemoveItem(10550,2): ItemCount=5
Items
10000, 2
10550, 3
Press <ENTER> to terminate client.
Para configurar, compilar e executar o exemplo
Instale ASP.NET 4.0 usando o comando a seguir.
%windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enableVerifique se você executou o Procedimento de instalação avulsa dos exemplos do Windows Communication Foundation.
Para criar a solução, siga as instruções na criação dos exemplos do Windows Communication Foundation.
Para executar o exemplo em uma configuração única ou entre máquinas, siga as instruções em Executando os exemplos do Windows Communication Foundation.