mirror of
https://github.com/boostorg/cobalt.git
synced 2026-01-19 16:12:15 +00:00
62 lines
1.3 KiB
Plaintext
62 lines
1.3 KiB
Plaintext
== Generator with push value
|
|
|
|
Coroutines with push values are not as common,
|
|
but can simplify certain issues significantly.
|
|
|
|
Since we've already got a json_reader in the previous example,
|
|
here's how we can write a json_writer that gets values pushed in.
|
|
|
|
The advantage of using a generator is the internal state management.
|
|
|
|
[source,cpp]
|
|
----
|
|
cobalt::generator<system::error_code, json::object>
|
|
json_writer(websocket_type & ws)
|
|
try
|
|
{
|
|
char buffer[4096];
|
|
json::serializer ser;
|
|
|
|
while (ws.is_open()) // <1>
|
|
{
|
|
auto val = co_yield system::error_code{}; // <2>
|
|
|
|
while (!ser.done())
|
|
{
|
|
auto sv = ser.read(buffer);
|
|
co_await ws.cobalt_write({sv.data(), sv.size()}); // <3>
|
|
}
|
|
|
|
}
|
|
co_return {};
|
|
}
|
|
catch (system::system_error& e)
|
|
{
|
|
co_return e.code();
|
|
}
|
|
catch (std::exception & e)
|
|
{
|
|
std::cerr << "Error reading: " << e.what() << std::endl;
|
|
throw;
|
|
}
|
|
----
|
|
<1> Keep running as long as the socket is open
|
|
<2> `co_yield` the current error and retrieve a new value.
|
|
<3> Write a frame to the websocket
|
|
|
|
Now we can use the generator like this:
|
|
|
|
[source,cpp]
|
|
----
|
|
auto g = json_writer(my_ws);
|
|
|
|
extern std::vector<json::value> to_write;
|
|
|
|
for (auto && tw : std::move(to_write))
|
|
{
|
|
if (auto ec = co_await g(std::move(tw)))
|
|
return ec; // yield error
|
|
}
|
|
----
|
|
|