Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O exemplo Stream demonstra o uso do modo de transferência em streaming. O serviço expõe várias operações que enviam e recebem transmissões. Este exemplo é auto-hospedado. Tanto o cliente quanto o serviço são programas de console.
Observação
O procedimento de configuração e as instruções de compilação para este exemplo estão localizados no final deste tópico.
O Windows Communication Foundation (WCF) pode se comunicar em dois modos de transferência: buffer ou streaming. No modo de transferência em buffer padrão, uma mensagem deve ser completamente entregue antes que um recetor possa lê-la. No modo de transferência de streaming, o recetor pode começar a processar a mensagem antes que ela seja completamente entregue. O modo de streaming é útil quando a informação que é passada é longa e pode ser processada em série. O modo de streaming também é útil quando a mensagem é muito grande para ser totalmente armazenada em buffer.
Contratos de Streaming e Serviços
O streaming é algo a ser considerado ao projetar um contrato de serviço. Se uma operação receber ou retornar grandes quantidades de dados, você deve considerar o streaming desses dados para evitar a alta utilização de memória devido ao buffer de mensagens de entrada ou saída. Para transmitir dados, o parâmetro que contém esses dados deve ser o único parâmetro na mensagem. Por exemplo, se a mensagem de entrada é a que será transmitida, a operação deve ter exatamente um parâmetro de entrada. Da mesma forma, se a mensagem de saída deve ser transmitida, a operação deve ter exatamente um parâmetro de saída ou um valor de retorno. Em ambos os casos, o parâmetro ou o tipo de valor de retorno deve ser Stream, Messageou IXmlSerializable. A seguir está o contrato de serviço usado neste exemplo de streaming.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IStreamingSample
{
[OperationContract]
Stream GetStream(string data);
[OperationContract]
bool UploadStream(Stream stream);
[OperationContract]
Stream EchoStream(Stream stream);
[OperationContract]
Stream GetReversedStream();
}
A GetStream operação recebe alguns dados de entrada como uma cadeia de caracteres, que é armazenada em buffer, e retorna um Stream, que é transmitido. Por outro lado, UploadStream recebe um Stream (transmitido) e retorna um bool (armazenado em buffer).
EchoStream toma e retorna Stream e é um exemplo de uma operação cujas mensagens de entrada e saída são transmitidas. Finalmente, GetReversedStream não recebe entradas e retorna um Stream (transmitido).
Ativando transferências em streaming
A definição de contratos de operação conforme descrito anteriormente fornece streaming no nível do modelo de programação. Se você parar por aí, o transporte ainda armazenará em buffer todo o conteúdo da mensagem. Para habilitar o streaming de transporte, selecione um modo de transferência no elemento de ligação do transporte. O elemento binding tem uma TransferMode propriedade que pode ser definida como Buffered, Streamed, StreamedRequest, ou StreamedResponse. Definir o modo de transferência para Streamed permite a comunicação de streaming em ambas direções. Definir o modo de transferência para StreamedRequest ou StreamedResponse permite a comunicação em streaming apenas na solicitação ou resposta, respectivamente.
O basicHttpBinding expõe a propriedade TransferMode na ligação, tal como fazem NetTcpBinding e NetNamedPipeBinding. Para outros transportes, você deve criar uma associação personalizada para definir o modo de transferência.
O seguinte código de configuração do exemplo mostra como definir a propriedade TransferMode para streaming em basicHttpBinding e uma ligação HTTP personalizada:
<!-- An example basicHttpBinding using streaming. -->
<basicHttpBinding>
<binding name="HttpStreaming" maxReceivedMessageSize="67108864"
transferMode="Streamed"/>
</basicHttpBinding>
<!-- An example customBinding using HTTP and streaming.-->
<customBinding>
<binding name="Soap12">
<textMessageEncoding messageVersion="Soap12WSAddressing10" />
<httpTransport transferMode="Streamed"
maxReceivedMessageSize="67108864"/>
</binding>
</customBinding>
Além de definir o transferMode para Streamed, o código de configuração anterior define o maxReceivedMessageSize para 64MB. Como mecanismo de defesa, maxReceivedMessageSize coloca um limite no tamanho máximo permitido de mensagens recebidas. O padrão maxReceivedMessageSize é 64 KB, que geralmente é muito baixo para cenários de streaming.
Processando dados à medida que são transmitidos
As operações GetStream, UploadStream e EchoStream todas lidam com o envio de dados diretamente de um arquivo ou salvar os dados recebidos diretamente em um arquivo. No entanto, em alguns casos, há um requisito para enviar ou receber grandes quantidades de dados e executar algum processamento em partes dos dados à medida que são enviados ou recebidos. Uma maneira de abordar esses cenários é escrever um fluxo personalizado (uma classe que deriva de Stream) que processa dados à medida que são lidos ou gravados. A GetReversedStream operação e a ReverseStream classe são um exemplo disso.
GetReversedStream cria e retorna uma nova instância do ReverseStream. O processamento real acontece quando o sistema lê a partir desse ReverseStream objeto. A ReverseStream.Read implementação lê um pedaço de bytes do arquivo subjacente, reverte-os e, em seguida, retorna os bytes invertidos. Isso não reverte todo o conteúdo do arquivo; ele reverte um pedaço de bytes de cada vez. Este é um exemplo para mostrar como você pode executar o processamento de fluxo à medida que o conteúdo está sendo lido ou gravado de e para o fluxo.
class ReverseStream : Stream
{
FileStream inStream;
internal ReverseStream(string filePath)
{
//Opens the file and places a StreamReader around it.
inStream = File.OpenRead(filePath);
}
// Other methods removed for brevity.
public override int Read(byte[] buffer, int offset, int count)
{
int countRead=inStream.Read(buffer, offset,count);
ReverseBuffer(buffer, offset, countRead);
return countRead;
}
public override void Close()
{
inStream.Close();
base.Close();
}
protected override void Dispose(bool disposing)
{
inStream.Dispose();
base.Dispose(disposing);
}
void ReverseBuffer(byte[] buffer, int offset, int count)
{
int i, j;
for (i = offset, j = offset + count - 1; i < j; i++, j--)
{
byte currenti = buffer[i];
buffer[i] = buffer[j];
buffer[j] = currenti;
}
}
}
Executar o teste
Para executar o exemplo, primeiro crie o serviço e o cliente seguindo as instruções no final deste documento. Em seguida, inicie o serviço e o cliente em duas janelas de console diferentes. Quando o cliente é iniciado, ele espera que você pressione ENTER quando o serviço estiver pronto. O cliente chama então os métodos GetStream(), UploadStream() e GetReversedStream() primeiro por HTTP e depois por TCP. Aqui está um exemplo de saída do serviço seguido por exemplo de saída do cliente:
Saída do serviço:
The streaming service is ready.
Press <ENTER> to terminate service.
Saving to file D:\...\uploadedfile
......................
File D:\...\uploadedfile saved
Saving to file D:\...\uploadedfile
...............
File D:\...\uploadedfile saved
Saída do cliente:
Press <ENTER> when service is ready
------ Using HTTP ------
Calling GetStream()
Saving to file D:\...\clientfile
......................
Wrote 33405 bytes to stream
File D:\...\clientfile saved
Calling UploadStream()
Calling GetReversedStream()
Saving to file D:\...\clientfile
......................
Wrote 33405 bytes to stream
File D:\...\clientfile saved
------ Using Custom HTTP ------
Calling GetStream()
Saving to file D:\...\clientfile
...............
Wrote 33405 bytes to stream
File D:\...\clientfile saved
Calling UploadStream()
Calling GetReversedStream()
Saving to file D:\...\clientfile
...............
Wrote 33405 bytes to stream
File D:\...\clientfile saved
Press <ENTER> to terminate client.
Para configurar, compilar e executar o exemplo
Verifique se você executou o procedimento de instalação do One-Time para os exemplos do Windows Communication Foundation.
Para criar a edição C# ou Visual Basic .NET da solução, siga as instruções em Criando os exemplos do Windows Communication Foundation.
Para executar o exemplo em uma configuração de máquina única ou cruzada, siga as instruções em Executando os exemplos do Windows Communication Foundation.
Observação
Se utilizares Svcutil.exe para regenerar a configuração desta amostra, certifica-te de modificar o nome do endpoint na configuração do cliente para corresponder ao código do cliente.