Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*.lo
*.o
*.obj
*.txt
*.tmp

# Precompiled Headers
*.gch
Expand Down
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,56 @@ async_simple::coro::Lazy<void> test_download() {
}
```

### chunked request and SSE

普通字符串请求体如果希望用chunked 方式发送,可以使用`async_post_chunked` 或者`async_request_chunked`;文件、iostream 或自定义异步数据源仍然使用`async_upload_chunked`。

```c++
async_simple::coro::Lazy<void> test_chunked_request() {
coro_http_client client{};
auto result = co_await client.async_post_chunked(
"http://127.0.0.1:9001/chunked", "hello chunked string");
assert(result.status == 200);
}
```

SSE(Server-Sent Events) 基于`text/event-stream`,cinatra 的SSE 实现复用chunked 传输。服务端通过`begin_sse`、`write_sse_event`、`end_sse` 写事件流,客户端通过`async_get_sse` 读取解析后的`sse_event`。

```c++
async_simple::coro::Lazy<void> test_sse() {
coro_http_server server(1, 9001);
server.set_http_handler<GET>(
"/sse",
[](coro_http_request &req,
coro_http_response &resp) -> async_simple::coro::Lazy<void> {
auto *conn = resp.get_conn();
bool ok = co_await conn->begin_sse();
if (!ok) {
co_return;
}

sse_event event{.event = "message", .data = "hello", .id = "1"};
ok = co_await conn->write_sse_event(event);
if (!ok) {
co_return;
}

co_await conn->end_sse();
});

server.async_start();
std::this_thread::sleep_for(200ms);

coro_http_client client{};
auto result = co_await client.async_get_sse(
"http://127.0.0.1:9001/sse", [](const sse_event &event) {
std::cout << event.event << ": " << event.data << "\n";
return true;
});
assert(result.status == 200);
}
```

### web socket
```c++
async_simple::coro::Lazy<void> test_websocket() {
Expand Down
51 changes: 50 additions & 1 deletion example/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,59 @@ async_simple::coro::Lazy<void> chunked_upload_download() {
assert(result.status == 200);
assert(result.resp_body == "chunked ok");

result = co_await client.async_post_chunked("http://127.0.0.1:9001/chunked",
"hello chunked string");
assert(result.status == 200);
assert(result.resp_body == "chunked ok");

result = co_await client.async_get("http://127.0.0.1:9001/write_chunked");
assert(result.status == 200);
assert(result.resp_body == "hello world ok");
}

async_simple::coro::Lazy<void> use_sse() {
coro_http_server server(1, 9001);
server.set_http_handler<cinatra::GET>(
"/sse",
[](coro_http_request& req,
coro_http_response& resp) -> async_simple::coro::Lazy<void> {
auto* conn = resp.get_conn();
bool ok = co_await conn->begin_sse();
if (!ok) {
co_return;
}

sse_event event{.event = "message", .data = "hello\nworld", .id = "1"};
ok = co_await conn->write_sse_event(event);
if (!ok) {
co_return;
}

ok = co_await conn->write_sse_data("done");
if (!ok) {
co_return;
}

co_await conn->end_sse();
});
server.async_start();
std::this_thread::sleep_for(200ms);

std::vector<sse_event> events;
coro_http_client client{};
auto result = co_await client.async_get_sse(
"http://127.0.0.1:9001/sse", [&events](const sse_event& event) {
events.push_back(event);
return true;
});
assert(result.status == 200);
assert(events.size() == 2);
assert(events[0].event == "message");
assert(events[0].data == "hello\nworld");
assert(events[0].id == "1");
assert(events[1].data == "done");
}

async_simple::coro::Lazy<void> use_websocket() {
coro_http_server server(1, 9001);
server.set_http_handler<cinatra::GET>(
Expand Down Expand Up @@ -560,7 +608,8 @@ int main() {
async_simple::coro::syncAwait(static_file_server());
async_simple::coro::syncAwait(use_websocket());
async_simple::coro::syncAwait(chunked_upload_download());
async_simple::coro::syncAwait(use_sse());
async_simple::coro::syncAwait(byte_ranges_download());
async_simple::coro::syncAwait(rlimiter_usage());
return 0;
}
}
Loading
Loading