Repository navigation
Expand file tree
/
Copy pathexample_ws.hpp
More file actions
43 lines (42 loc) · 1.71 KB
/
Copy pathexample_ws.hpp
File metadata and controls
43 lines (42 loc) · 1.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/* Copyright (C) 2026 Sebastiano Merlino; SPDX-License-Identifier: LGPL-2.1-or-later */
#ifndef EXAMPLES_EXAMPLE_WS_HPP_
#define EXAMPLES_EXAMPLE_WS_HPP_
#include <chrono>
#include <utility>
#include <httpserver/exchange.hpp>
namespace v3_example {
inline httpserver::task<void> echo_websocket(httpserver::exchange& x, httpserver::ws_upgrade_options options = {}) {
auto upgraded = co_await x.upgrade(std::move(options));
if (!upgraded.status.ok()) {
if (upgraded.rejection_fields.count("Content-Length") == 0) {
upgraded.rejection_fields.append("Content-Length", "0");
}
x.respond(upgraded.rejection_status, upgraded.rejection_fields);
co_return;
}
auto session = std::move(*upgraded.session);
httpserver::resume_signal closed;
session.on_close([closed](httpserver::websocket::close_info) mutable { closed.signal(); });
bool sending = true;
while (sending) {
const auto received = co_await session.receive();
if (!received.status.ok() || !received.value) {
break;
}
for (;;) {
const auto sent = session.try_send(received.value->kind, received.value->data);
if (sent.disposition == httpserver::websocket::send_disposition::accepted) {
break;
}
if (sent.disposition != httpserver::websocket::send_disposition::backpressured ||
!(co_await session.writable()).ok()) {
sending = false;
break;
}
}
}
// Every exit retains the owning session through a bounded close notification.
co_await closed.wait_for(std::chrono::seconds(5));
}
} // namespace v3_example
#endif // EXAMPLES_EXAMPLE_WS_HPP_