Compartilhar via


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

  1. Verifique se você executou o Procedimento de instalação única para os exemplos do Windows Communication Foundation.

  2. 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.

  3. 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.