使用 C++20 实现异步网络访问

libfv 介绍

libfv是一个极简异步HTTP库,支持tcp、HTTP1.1、websocket的客户端/服务器等功能,可以通过它轻易实现HTTP异步开发。如果你刚好喜欢C++20异步,那么libfv就是你的最佳选择

文档地址:https://libfv.fawdlstty.com/zh_hans/

注意:使用这个库之前,首先需要知道 co_await 关键字的作用

  • 推荐异步学习文档:使用 Async 和 Await 的异步编程,微软官方出品C#语言的异步教程,将async关键字省略,await关键字换成co_await,就和C++的几乎一样了
  • 推荐异步学习文档:stackless与await,如果想要深入了解co_await关键字的实现思路那么不可错过

废话不多说,教大家如何使用。首先安装:

vcpkg install fawdlstty-libfv

然后,就可以使用libfv啦。

同步转异步

libfv既然是异步HTTP库,那么使用网络功能首先需要在异步函数里调用。众所周知,main函数是同步函数,因此,我们需要在main函数里发起异步任务。我们此处同步方法转异步方法:

#include <fv/fv.h>

Task<void> async_func () {
	// 后面会写到异步功能的代码,将其粘贴到此处就可以啦
}

int main () {
	fv::Tasks::Init ();
	fv::Tasks::RunAsync (async_func);
	fv::Tasks::LoopRun ();
	fv::Tasks::Release ();
	return 0;
}

http client

libfv有个非常棒的特性是,内部维护连接池。只要schema(http或https)、域名、端口都相同,那么连接会自动复用。这特性将极大降低高频客户端的连接维护成本。

注:连接池在libfv 0.0.7版本开始支持。另外libfv的http客户端功能比此处介绍更强。详见文档

fv::Response _r1 = co_await fv::Get ("https://t.cn");
fv::Response _r2 = co_await fv::Post ("https://t.cn", fv::body_kv ("a", "1"), fv::body_kv ("b", "2"));

websocket client

接下来是websocket客户端。同样也非常简单。以下代码即实现websocket的发送,以及循环接收后续数据:

std::shared_ptr<fv::WsConn> _conn = co_await fv::ConnectWS ("wss://t.cn/ws");
co_await _conn->SendText ("hello", 5);
while (true) {
	auto [_data, _type] = co_await _conn->Recv ();
	std::cout << _data << std::endl;
}

http server

客户端基本使用介绍完毕。下面说说服务器端。我们来实现一个http服务器端,简单的返回hello world的功能:

fv::HttpServer _server {};
_server.SetHttpHandler ("/hello", [] (fv::Request &_req) -> Task<fv::Response> {
	co_return fv::Response::FromText ("hello world");
});
co_await _server.Run (8080);

以上代码运行之后,浏览器里请求 http://127.0.0.1:8080/hello,即可看到效果。

websocket server

websocket服务器端其实就是http服务器端,只不过监听之后处理函数的处理步骤不同而已,区别就是,判断客户端是否为websocket连接,如果是,那么升级为websocket连接即可:

fv::HttpServer _server {};
_server.SetHttpHandler ("/ws", [] (fv::Request &_req) -> Task<fv::Response> {
	if (_req.IsWebsocket ()) {
		auto _conn = co_await _req.UpgradeWebsocket ();
		while (true) {
			auto [_data, _type] = co_await _conn->Recv ();
			if (_type == fv::WsType::Text) {
				co_await _conn->SendText (_data.data (), _data.size ());
			} else if (_type == fv::WsType::Binary) {
				co_await _conn->SendBinary (_data.data (), _data.size ());
			}
		}
		co_return fv::Response::Empty ();
	} else {
		co_return fv::Response::FromText ("please use websocket");
	}
});
co_await _server.Run (8080);

后续客户端通过 ws://127.0.0.1:8080/ws 即可实现连接websocket服务器。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值