当前位置: 首页 > article >正文

Libevent库-http通信不同请求方式的处理

做项目的时候用到了http通信,同事用libevent库写的,特此记录后端从前端拿到消息后的处理方式

void CHTTPTest::request(const std::any & data)
{
	// data 是从前端拿到的数据
	void *obj = std::any_cast<void *>(data); // std::any是C++17新标准的
	struct evhttp_request *req = (evhttp_request*)(obj);
	enum evhttp_cmd_type method = evhttp_request_get_command(req);  // 获取请求方法

	if (method == EVHTTP_REQ_GET)
	{
		// GET 请求
		this->getProcess(req);
	}
	else if (method == EVHTTP_REQ_POST)
	{
		// POST 请求
		this->postProcess(req);
	}
	else
	{
		// 错误
		this->return_msg(req, "Unsupported request method.", ErrorCode::fail);
	}
}

GET的请求处理,包括前端请求的参数

void CHTTPTest::getProcess(evhttp_request * req)
{
	//获取请求uri
	const char* uri = evhttp_request_get_uri(req);
	//解码uri
	struct evhttp_uri* decoded_uri = evhttp_uri_parse(uri);
	if (!decoded_uri)
	{
		return_msg(req, "Failed to parse URI\n", ErrorCode::fail);
		return;
	}
	// 找到路径
	QString path = evhttp_uri_get_path(decoded_uri);
	if (path.isEmpty())
	{
		path = "/";
	}
	//解析查询字符串
	struct evkeyvalq params;
	evhttp_parse_query(uri, &params);
	struct evkeyval* kv;
	// 创建 QVariantHash 用于存储参数
	//QVariantHash paramList;
	// 创建 JSON 对象用于存储查询参数
	QJsonObject jsonObj;

	// 遍历查询参数,将其添加到 JSON 对象中
	for (kv = params.tqh_first; kv; kv = kv->next.tqe_next)
	{
		jsonObj[kv->key] = kv->value;

	}
	// 清理查询参数的内存
	evhttp_clear_headers(&params);
	// 创建 JSON 文档
	QJsonDocument JsonDoc = QJsonDocument(jsonObj);
	// 检查 JSON 对象是否为空,返回相应的消息
	QString Info = JsonDoc.toJson(QJsonDocument::Compact);

	// 将 JSON 文档转换为字符串并使用紧凑格式
	if (jsonObj.isEmpty())
	{
		return_msg(req, "Param Is Empty\n", ErrorCode::fail);
		return;
	}
	else
	{
		// 逻辑处理接口
		this->logicProcess(req, path, jsonObj);
	}
}

POST的请求处理,包括前端发送的参数处理

void CHTTPTest::postProcess(evhttp_request * req)
{
	const char* uri = evhttp_request_get_uri(req);

	struct evhttp_uri* decoded_uri = evhttp_uri_parse(uri);
	if (!decoded_uri)
	{
		printf("Failed to parse URI\n");
		return;
	}

	QString path = evhttp_uri_get_path(decoded_uri);
	if (path.isEmpty())
	{
		path = "/";
	}

	struct evbuffer* input_buf = evhttp_request_get_input_buffer(req);
	size_t data_len = evbuffer_get_length(input_buf);

	char* data = (char*)malloc(data_len + 1);
	if (data)
	{
		evbuffer_copyout(input_buf, data, data_len);
		data[data_len] = '\0';
		QJsonParseError parseError;
		QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
		if (parseError.error != QJsonParseError::NoError)
		{
			this->return_msg(req, parseError.errorString(), ErrorCode::fail);
			return;
		}
		QJsonObject jsonObj = doc.object();
		// 逻辑处理接口
		this->logicProcess(req, path, jsonObj);
	}
}

内部消息返回前端的处理

void CDigitalModelManage::return_msg(evhttp_request * req, QString msg, int errCode)
{
	struct evbuffer* buf = evbuffer_new();
	if (!buf)
	{
		return;
	}
	QJsonParseError parseError;
	QJsonDocument jsonDoc = QJsonDocument::fromJson(msg.toUtf8(), &parseError);
	QJsonObject jsonObject;
	QJsonDocument backJsonDoc;
	if (parseError.error == QJsonParseError::NoError)
	{
		jsonObject = jsonDoc.object();
		jsonObject["code"] = errCode;
	}
	else
	{
		jsonObject["code"] = errCode;
		jsonObject["message"] = msg;
	}
	backJsonDoc = QJsonDocument(jsonObject);
	QString backInfo = backJsonDoc.toJson(QJsonDocument::Compact);	
	evbuffer_add_printf(buf, backInfo.toUtf8().constData());
	evhttp_add_header(req->output_headers, "Content-Type", "application/json; charset=utf-8");
	evhttp_send_reply(req, HTTP_OK, "OK", buf);
	evbuffer_free(buf);	
}

在接口logicProcess中处理就是各个消息的内部逻辑处理了,传的第一个参数是http请求的内存块(我是这么理解的),第二个参数是和前端约定的URL,第三个参数就是前端发送的JSON体。只需要在接口logicProcess中解这个JSON体就可以拿到值了。
这里只是一部分代码,比如怎么调用request接口还需要研究研究,只是作为记录,方便后续学习参考。


http://www.kler.cn/a/416490.html

相关文章:

  • Android笔记(三十四):封装带省略号图标结尾的TextView
  • Windows加固脚本
  • 使用YOLOv3进行实时活体检测:Python与OpenCV实现
  • ERROR in [eslint] Invalid Options ‘extensions‘ has been removed.
  • 三、计算机视觉_08YOLO目标检测
  • k8s 20版本以上,有了 CoreDNS作为域名解析服务器了,pod通过域名相互访问,需要额外配置dns条目吗
  • 哪些行业对六西格玛管理方法的需求较大?
  • 基于若依框架和Vue2 + Element-UI 实现图片上传组件的重写与优化
  • Python 3 教程第34篇(MySQL 数据库连接 - PyMySQL 驱动)
  • 表征对齐在训练DiT模型中的重要性
  • PHP ODBC:连接数据库的桥梁
  • ASP.NET Core面试题汇总
  • 首发VM手眼标定xml文件点位取出以及转其他格式
  • 【Python】深入理解Python的字符串处理与正则表达式:文本处理的核心技能
  • A054-基于Spring Boot的青年公寓服务平台
  • docker从入门到入土
  • 【Linux】常见指令 + 权限概念
  • 计算机网络:TCP/IP 协议职责和常见的三种模型介绍
  • HCIA笔记5--STP协议
  • Django-Vue3-Admin - 现代化的前后端分离权限管理系统
  • 53 基于单片机的8路抢答器加记分
  • MySql(面试题理解B+树原理 实操加大白话)
  • 如何在HarmonyOS NEXT中处理页面间的数据传递?
  • logminer挖掘日志归档查找问题
  • 深入理解Oracle DB的锁和闩
  • elementUI非常规数据格式渲染复杂表格(副表头、合并单元格)