Como trabalhar com fluxos assíncronos (C++ REST SDK)
O C++ REST SDK (codinome "Casablanca") fornece a funcionalidade de fluxo que permite que você trabalhe com mais facilidade com soquetes TCP, arquivos em disco e memória. Os fluxos do C++ REST SDK se assemelham aos fornecidos pela Biblioteca Padrão C++, exceto que as versões do C++ REST SDK fazem uso de assincronia. A biblioteca retorna pplx::task, e não o valor diretamente, para operações de E/S que podem ser potencialmente bloqueadas. Esta página mostra dois exemplos. O primeiro mostra como gravar e ler por meio de um fluxo usando contêineres STL e memória bruta. O segundo exemplo cria uma solicitação HTTP GET e imprime parte de seu fluxo de resposta no console.
Aviso
Este tópico contém informações para o C++ REST SDK 1.0 (codinome "Casablanca").Se você estiver usando uma versão mais recente da página da Web do Codeplex Casablanca, use então a documentação local em http://casablanca.codeplex.com/documentation.
Um exemplo mais completo que mostra as instruções #include e using é apresentado nesses exemplos.
Para usar fluxos junto com contêineres STL e memória bruta
Este exemplo demonstra como gravar e ler por meio de um fluxo usando contêineres STL e memória bruta.
// Shows how to read from and write to a stream with an STL container or raw pointer.
void ReadWriteStream(istream inStream, ostream outStream)
{
// Write a string to the stream.
std::string strData("test string to write\n");
container_buffer<std::string> outStringBuffer(std::move(strData));
outStream.write(outStringBuffer, outStringBuffer.collection().size()).then([](size_t bytesWritten)
{
// Perform actions here once the string has been written...
});
// Read a line from the stream into a string.
container_buffer<std::string> inStringBuffer;
inStream.read_line(inStringBuffer).then([inStringBuffer](size_t bytesRead)
{
const std::string &line = inStringBuffer.collection();
// Perform actions here after reading line into a string...
});
// Write data from a raw chunk of contiguous memory to the stream.
// The raw data must stay alive until write operation has finished.
// In this case we will place on the heap to avoid any issues.
const size_t rawDataSize = 8;
unsigned char* rawData = new unsigned char[rawDataSize];
memcpy(&rawData[0], "raw data", rawDataSize);
rawptr_buffer<unsigned char> rawOutBuffer(rawData, rawDataSize, std::ios::in);
outStream.write(rawOutBuffer, rawDataSize).then([rawData](size_t bytesWritten)
{
delete []rawData;
// Perform actions here once the string as been written...
});
}
Para acessar um fluxo de resposta HTTP
Veja como usar o método web::http::http_response::body para recuperar um objeto concurrency::streams::istream do qual os dados podem ser lidos. Para simplificar, este exemplo imprime somente os primeiros caracteres da resposta no console. Para obter uma versão mais básica que recupera uma resposta do servidor, mas não funciona com o fluxo de resposta, consulte Como: conectar aos servidores HTTP.
// Creates an HTTP request and prints part of its response stream.
pplx::task<void> HTTPStreamingAsync()
{
http_client client(L"https://www.fourthcoffee.com");
return client.request(methods::GET).then([](http_response response)
{
if(response.status_code() != status_codes::OK)
{
// Handle error cases...
return pplx::task_from_result();
}
// Perform actions here reading from the response stream...
// In this example, we print the first 15 characters of the response to the console.
istream bodyStream = response.body();
container_buffer<std::string> inStringBuffer;
return bodyStream.read(inStringBuffer, 15).then([inStringBuffer](size_t bytesRead)
{
const std::string &text = inStringBuffer.collection();
// For demonstration, convert the response text to a wide-character string.
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> utf16conv;
std::wostringstream ss;
ss << utf16conv.from_bytes(text.c_str()) << std::endl;
std::wcout << ss.str();
});
});
/* Output:
<!DOCTYPE html>
*/
}
Exemplo completo
Veja o exemplo completo.
#include <codecvt>
#include <containerstream.h>
#include <http_client.h>
#include <iostream>
#include <producerconsumerstream.h>
#include <rawptrstream.h>
using namespace concurrency;
using namespace concurrency::streams;
using namespace web::http;
using namespace web::http::client;
// Shows how to read from and write to a stream with an STL container or raw pointer.
void ReadWriteStream(istream inStream, ostream outStream)
{
// Write a string to the stream.
std::string strData("test string to write\n");
container_buffer<std::string> outStringBuffer(std::move(strData));
outStream.write(outStringBuffer, outStringBuffer.collection().size()).then([](size_t bytesWritten)
{
// Perform actions here once the string has been written...
});
// Read a line from the stream into a string.
container_buffer<std::string> inStringBuffer;
inStream.read_line(inStringBuffer).then([inStringBuffer](size_t bytesRead)
{
const std::string &line = inStringBuffer.collection();
// Perform actions here after reading line into a string...
});
// Write data from a raw chunk of contiguous memory to the stream.
// The raw data must stay alive until write operation has finished.
// In this case we will place on the heap to avoid any issues.
const size_t rawDataSize = 8;
unsigned char* rawData = new unsigned char[rawDataSize];
memcpy(&rawData[0], "raw data", rawDataSize);
rawptr_buffer<unsigned char> rawOutBuffer(rawData, rawDataSize, std::ios::in);
outStream.write(rawOutBuffer, rawDataSize).then([rawData](size_t bytesWritten)
{
delete []rawData;
// Perform actions here once the string as been written...
});
}
// Creates an HTTP request and prints part of its response stream.
pplx::task<void> HTTPStreamingAsync()
{
http_client client(L"https://www.fourthcoffee.com");
return client.request(methods::GET).then([](http_response response)
{
if(response.status_code() != status_codes::OK)
{
// Handle error cases...
return pplx::task_from_result();
}
// Perform actions here reading from the response stream...
// In this example, we print the first 15 characters of the response to the console.
istream bodyStream = response.body();
container_buffer<std::string> inStringBuffer;
return bodyStream.read(inStringBuffer, 15).then([inStringBuffer](size_t bytesRead)
{
const std::string &text = inStringBuffer.collection();
// For demonstration, convert the response text to a wide-character string.
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> utf16conv;
std::wostringstream ss;
ss << utf16conv.from_bytes(text.c_str()) << std::endl;
std::wcout << ss.str();
});
});
/* Output:
<!DOCTYPE html>
*/
}
int wmain()
{
// This example uses the task::wait method to ensure that async operations complete before the app exits.
// In most apps, you typically don�t wait for async operations to complete.
streams::producer_consumer_buffer<uint8_t> buffer;
//ReadWriteStream(buffer.create_istream(), buffer.create_ostream());
HTTPStreamingAsync().wait();
}