Freigeben über


Gewusst wie: Arbeiten mit asynchronen Streams (C++-REST-SDK)

Das C++ REST SDK (Codename "Casablanca") bietet Streamfunktionalität, die das Arbeiten mit TCP-Sockets, Dateien auf einem Datenträger und Arbeitsspeicher vereinfacht. C++ REST SDK-Streams ähneln denen der C++-Standardbibliothek, mit dem Unterschied, dass die C++ REST SDK-Versionen Asynchronität ermöglichen. Die Bibliothek gibt bei E/A-Vorgängen, die möglicherweise blockieren, pplx::task und nicht den Wert direkt zurück. Diese Seite zeigt zwei Beispiele. Das erste zeigt, wie mit STL-Containern und unformatiertem Speicher aus einem Stream gelesen und in ihn geschrieben werden kann. Im zweiten Beispiel wird eine HTTP GET-Anforderung erstellt und ein Teil ihres Antwortstreams in die Konsole ausgegeben.

Warnung

Dieses Thema enthält Informationen für das C++ REST SDK 1.0 (Codename "Casablanca").Wenn Sie eine neuere Version von der Webseite "Codeplex Casablanca" verwenden, dann verwenden Sie die lokale Dokumentation unter http://casablanca.codeplex.com/documentation.

Ein etwas vollständigeres Beispiel, das die #include- und using-Anweisungen veranschaulicht, folgt danach.

So verwenden Sie Streams zusammen mit STL-Containern und unformatiertem Speicher

Dieses Beispiel veranschaulicht, wie mit STL-Containern und unformatiertem Speicher aus einem Stream gelesen und in ihn geschrieben werden kann.

// 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...
    });
}

So greifen Sie auf einen HTTP-Antwortstream zu

Im Folgenden wird gezeigt, wie die web::http::http_response::body-Methode verwendet wird, um ein concurrency::streams::istream-Objekt abzurufen, aus dem Daten gelesen werden können. Der Einfachheit halber werden in diesem Beispiel nur die ersten Zeichen der Antwort in die Konsole ausgegeben. Eine etwas einfachere Version, mit der eine Serverantwort abgerufen wird, die aber nicht nicht mit dem Antwortstream verwendet werden kann, finden Sie unter Gewusst wie: Verbinden mit HTTP-Servern.

// 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>
    */
}

Vollständiges Beispiel

Im Folgenden sehen Sie das vollständige Beispiel:

#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();
}

Siehe auch

Weitere Ressourcen

C++-REST-SDK (Codename "Casablanca")