uchenily / uvio

c++20 coroutines runtime driven by libuv
MIT License
5 stars 0 forks source link
asynchronous codec coroutines cross-platform event-driven http io libuv modern-cpp network socks5 stackless websocket

uvio

GitHub License Static Badge Static Badge GitHub top language Actions Status Actions Status Actions Status

C++20 coroutines + libuv

示例

tcp echo server ```c++ #include "uvio/core.hpp" #include "uvio/net.hpp" using namespace uvio; using namespace uvio::net; // Ignore errors auto process(TcpStream stream) -> Task<> { while (true) { std::array buf{}; if (auto ret = co_await stream.read(buf); !ret) { console.error(ret.error().message()); break; } console.info("Received: `{}`", buf.data()); if (auto ret = co_await stream.write(buf); !ret) { console.error(ret.error().message()); break; } } co_return; } auto server() -> Task<> { std::string host{"0.0.0.0"}; int port{8000}; auto listener = TcpListener(); listener.bind(host, port); console.info("Listening on {}:{} ...", host, port); while (true) { auto stream = (co_await listener.accept()).value(); spawn(process(std::move(stream))); } } auto main() -> int { block_on(server()); } ``` ```bash # 客户端 telnet localhost 8000 # 或者 nc localhost 8000 -v ```
http server ```cpp #include "uvio/net/http.hpp" using namespace uvio::net::http; auto main() -> int { HttpServer server{"0.0.0.0", 8000}; server.add_route("/", [](const HttpRequest &req, HttpResponse &resp) { resp.body = std::format("{} {}\r\nhello", req.method, req.uri); }); server.add_route("/test", [](const HttpRequest &req, HttpResponse &resp) { resp.body = std::format("{} {}\r\ntest route", req.method, req.uri); }); server.run(); } ``` ```bash # 客户端 curl localhost:8000/ -v ```
websocket server/client ```cpp #include "uvio/net/http.hpp" #include "uvio/net/websocket.hpp" using namespace uvio::net::http; using namespace uvio::net; auto process_message(websocket::WebsocketFramed &channel) -> Task<> { // Ignore errors for (int i = 0; i < 64; i++) { auto msg = (co_await channel.recv()).value(); LOG_INFO("Received: `{}`", std::string_view{msg.data(), msg.size()}); co_await channel.send(msg); } co_await channel.close(); co_return; } auto main() -> int { websocket::WebsocketServer server{"0.0.0.0", 8000}; server.add_route("/", [](const HttpRequest &req, HttpResponse &resp) { resp.body = std::format("{} {}\r\nhello", req.method, req.uri); }); server.handle_message(process_message); server.run(); } ``` ```cpp #include "uvio/net/websocket.hpp" using namespace uvio::net; using namespace uvio; auto process_message(websocket::WebsocketFramed &channel) -> Task<> { // Ignore errors for (int i = 0; i < 64; i++) { auto msg = std::format("test message {} from client", i); co_await channel.send(msg); auto msg2 = (co_await channel.recv()).value(); LOG_INFO("Received: `{}`", std::string_view{msg2.data(), msg2.size()}); } co_await channel.close(); co_return; } auto main() -> int { websocket::WebsocketClient client{"127.0.0.1", 8000}; client.handle_message(process_message); client.run(); } ```
socks5 server 完整代码请查看 [socks5_server.cpp](./examples/socks5_server.cpp) ```cpp auto main() -> int { socks5::Socks5Server proxy{"0.0.0.0", 1080}; proxy.run(); } ``` 在使用浏览器情况下, 可以安装 `SwitchyOmega` 插件测试 在终端下可以使用 curl 命令进行测试: `curl -v http://www.baidu.com/ --proxy socks5://127.0.0.1:1080`

功能

原始目标

开始

meson setup build
meson compile -C build

安装

meson install -C build [--destdir xxx_path]

或者直接拷贝目录:

cp -r uvio xxx_path

编译器版本

clang (>= 17) 或 gcc (>= 13) 或 apple clang (>= 15) 或 MSVC (>= 19)

基准测试

benchmark

参与开发

如果有使用上的疑问或者任何ideas, 欢迎通过 Issues 或者 Discussions 分享

致谢

项目设计与实现参考了以下开源项目, 在此表示感谢!