STREAM
O exemplo de Streaming Demonstra o uso da comunicação no modo de transferência por streaming. O serviço expõe várias operações que enviam e recebem streaming. Este exemplo é auto-hospedado. O cliente e o serviço são programas de console.
Observação
O procedimento de instalação e as instruções de compilação desse exemplo estão no final deste tópico.
O WCF (Windows Communication Foundation) pode se comunicar em dois modos de transferência: em buffer ou por streaming. No modo de transferência em buffer padrão, uma mensagem deve ser entregue completamente para que um receptor possa lê-la. No modo de transferência por streaming, o receptor pode começar a processar a mensagem, antes que ela seja entregue completamente. O modo de streaming é útil quando as informações passadas são longas e podem ser processadas serialmente. O modo de streaming também é útil quando a mensagem é muito grande para ser totalmente armazenada em buffer.
Contratos de Streaming e Serviço
Considere o streaming ao criar um contrato de serviço. Se uma operação receber ou retornar grandes volumes de dados, transmita esses dados para evitar a alta utilização da 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 for a que será transmitida, a operação deverá ter exatamente um parâmetro de entrada. Da mesma forma, se a mensagem de saída for transmitida, a operação deverá ter exatamente um parâmetro de saída ou um valor retornado. Em ambos os casos, o tipo de valor de parâmetro ou de retorno deve ser Stream
, Message
ou IXmlSerializable
. Veja a seguir 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 operação GetStream
recebe alguns dados de entrada como uma cadeia de caracteres, que é armazenada em buffer, e retorna uma Stream
, que é transmitida. Por outro lado, UploadStream
recebe uma Stream
(transmitida) e retorna uma bool
(em buffer). EchoStream
usa e retorna Stream
e é um exemplo de uma operação cujas mensagens de entrada e saída são transmitidas. Por fim, GetReversedStream
não obtém entradas e retorna uma Stream
(transmitida).
Como habilitar transferências transmitidas
A definição de contratos de operação, conforme descrito anteriormente, fornece o 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 associação do transporte. O elemento de associação tem uma propriedade TransferMode
, que pode ser definida comoBuffered
, Streamed
, StreamedRequest
ou StreamedResponse
. Definir o modo de transferência para Streamed
habilita a comunicação de streaming em ambas as direções. Definir o modo de transferência como StreamedRequest
ou StreamedResponse
habilita a comunicação de streaming apenas na solicitação ou resposta, respectivamente.
O basicHttpBinding
expõe a propriedade TransferMode
na associação, assim como NetTcpBinding
e NetNamedPipeBinding
. Para outros transportes, você deve criar uma associação personalizada para definir o modo de transferência.
O código de configuração a seguir do exemplo mostra a configuração da propriedade TransferMode
para streaming no basicHttpBinding
e em uma associaçã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
como Streamed
, o código de configuração anterior define o maxReceivedMessageSize
como 64 MB. Como mecanismo de defesa, maxReceivedMessageSize
coloca um limite no tamanho máximo permitido para mensagens recebidas. O maxReceivedMessageSize
padrão é 64 KB, que geralmente é muito baixo para cenários de streaming.
Como processar dados à medida que são transmitidos
As operações GetStream
, UploadStream
e EchoStream
lidam com o envio de dados diretamente de um arquivo ou o salvamento de dados recebidos diretamente em um arquivo. No entanto, em alguns casos, é necessário enviar ou receber grandes volumes de dados e executar certo processamento em partes dos dados à medida que são enviados ou recebidos. Uma maneira de resolver esses cenários é gravar um streaming personalizado (uma classe derivada de Stream), que processa os dados à medida que são lidos ou gravados. A operação GetReversedStream
e a classe ReverseStream
são exemplos disso.
GetReversedStream
cria e retorna uma nova instância de ReverseStream
. O processamento real ocorre conforme o sistema lê a partir do objeto ReverseStream
. A implementação de ReverseStream.Read
lê uma parte dos bytes do arquivo subjacente, inverte-os e retorna os bytes invertidos. Esse método não inverte todo o conteúdo do arquivo, mas inverte uma parte dos bytes de cada vez. Este é um exemplo para mostrar como você pode executar o processamento de streaming, à medida que o conteúdo está sendo lido ou gravado no streaming.
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;
}
}
}
Executando o exemplo
Para executar o exemplo, primeiro crie o serviço e o cliente seguindo as instruções ao final deste documento. Em seguida, inicie o serviço e o cliente em duas janelas de console diferentes. Quando o cliente é iniciado, ele aguarda que você pressione ENTER quando o serviço estiver pronto. Em seguida, o cliente chama os métodos GetStream()
, UploadStream()
e GetReversedStream()
primeiro por HTTP e depois por TCP. Esta é uma saída de exemplo do serviço seguido da saída de exemplo 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 única para os exemplos do Windows Communication Foundation.
Para compilar a edição .NET do C# ou do Visual Basic da solução, siga as instruções contidas em Como Compilar as Amostras do Windows Communication Foundation.
Para executar o exemplo em uma configuração de computador único ou cruzado, siga as instruções em Como executar os exemplos do Windows Communication Foundation.
Observação
Se você usar Svcutil.exe para regenerar a configuração desta amostra, modifique o nome do ponto de extremidade na configuração do cliente para corresponder ao código do cliente.