IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 开源C++ http服务框架WHttpServer -> 正文阅读

[网络协议]开源C++ http服务框架WHttpServer

WHttpServer

gitee地址:https://gitee.com/fengxian21/whttp-server/

介绍

基于mongoose 7.3版本的源码,修改源码及二次封装,引入线程池编写的http服务,同时支持https。
使用示例可以查看HttpExample.cpp、HttpExample.h和main.cpp三个文件,里面分别举例了http普通接口、大文件上传、大文件下载3个典型场景。

操作系统:Linux

安装教程

直接将whttp-server-core目录里面的文件拷贝到自己的工程即可

接口说明

  1. bool init(int maxEventThreadNum),初始化线程池,指定线程池最大线程数
  2. bool startHttp(int port),开启http服务
  3. bool startHttps(int port, string certPath, string keyPath),开启https服务
  4. bool stop(),停止http和https服务,在析构函数函数里面已经调用
  5. bool run(),服务运行的发动机,外部必须用一个死循环一直调用该函数
  6. bool isRunning(),查看服务是否还在运行中
  7. void addHttpApi(const string &uri, HttpCbFun fun, int httpMethods),添加普通的http回调接口,其中httpMethods以数据的不同位职位代表不同的http方法,具体如下:
         #define W_HTTP_GET      (1 << 0)
         #define W_HTTP_POST     (1 << 1)
         #define W_HTTP_PUT      (1 << 2)
         #define W_HTTP_DELETE   (1 << 3)
         #define W_HTTP_HEAD     (1 << 4)
         #define W_HTTP_ALL      (1 << 15)
  1. void addChunkHttpApi(const string &uri, HttpCbFun fun, int httpMethods),添加数据块http回调接口,当客户端的http请求数据可能超过3M时,采用这个函数添加接口,典型的场景如文件上传
  2. void setHttpFilter(HttpFilterFun filter),设置http接口的过滤函数,若过滤函数filter返回false,则不会进入回调,用于需要如登录信息才会响应的接口
  3. void forceCloseHttpConnection(shared_ptr httpMsg),用于强行关闭socket连接,正常情况下,回调完成后,框架内部会自己关闭socket连接。但是有些情况下,比如文件下载时,客户端暂停了下载,而且暂停时间很久,这就导致服务器的某个线程的任务一直被卡主,不得不强制关闭socket
  4. void addSendMsgToQueue(shared_ptr httpMsg, const char* data, int len),向客户端返回数据,会先放入缓冲区,等待下次循环时再发送出去
  5. void addSendMsgToQueue(shared_ptr httpMsg, string *sendMsg),向客户端返回数据,上面函数的重载
  6. void httpReplyJson(shared_ptr httpMsg, int httpCode, string head, string body),向客户端返回数据,返回type是json,这是对上面2个函数进一步封装的便捷函数
  7. string formJsonBody(int code, string message),返回类似{“code”:0, “message”: “success”}的json字符串
  8. bool isClientDisconnect(shared_ptr httpMsg),返回客户端是否主动断开了连接
  9. shared_ptr deQueueHttpChunk(shared_ptr httpMsg),大文件上传的场景,获取chunk数据块

重要数据类型

  1. using HttpCbFun = std::function<void(shared_ptr &)>,http接口的回调函数
  2. using HttpFilterFun = std::function<bool(shared_ptr &)>,http接口的过滤函数
  3. HttpReqMsg结构体
 struct HttpReqMsg
{
   mg_connection *httpConnection = nullptr; // mongoose里面代表一个socket连接的结果体,外层不关心
   string method; // http方法,可以是GET POST PUT DELETE等
   string uri; 
   map<string, string> querys; // the params in uri
   string proto; // http version
   map<string, string> headers; // http头部字段,其中key都被转为了小写,比如"Content-Length" 转为了 "content-length"
   string body; // http body体数据
   int64_t totalBodySize; // http body体数据大小,就是头部"content-length"值
   shared_ptr<HttpChunkQueue> chunkQueue; // 大文件上传时,存储文件的数据块
   shared_ptr<HttpSendQueue> sendQueue; // http返回给客户端的数据队列
   int64_t recvChunkSize = 0; // 大文件上传时,已经接收到的数据块大小
   bool finishRecvChunk = false; // 大文件上传时,判断是否所有数据都上传完成了
};

注意事项

1、所有http回调函数都是在子线程里面运行的,即使同一个回调函数,每次运行也不一定在一个线程,注意线程安全
2、为了保证更好的性能,发动机函数run里面没有加锁,不是线程安全的,所以初始化之类的函数,如init、startHttp、addHttpApi之类的函数的调用需要在启动run函数之前运行,或者其和run函数在一个线程。

示例代码

初始化代码:

void HttpExample::start()
{
    _httpServer = new WHttpServer();
    _httpServer->init(32);
    HttpFilterFun filterFun = std::bind(&HttpExample::httpFilter, this, std::placeholders::_1);
    _httpServer->setHttpFilter(filterFun);
    _httpServer->startHttp(6200);

    HttpCbFun normalCbFun = std::bind(&HttpExample::handleHttpRequestTest, this, std::placeholders::_1);
    _httpServer->addChunkHttpApi("/whttpserver/test", normalCbFun, W_HTTP_GET);

    HttpCbFun bigFileUploadCbFun = std::bind(&HttpExample::handleHttpBigFileUpload, this, std::placeholders::_1);
    _httpServer->addChunkHttpApi("/whttpserver/bigfileupload", bigFileUploadCbFun, W_HTTP_POST | W_HTTP_PUT);

    HttpCbFun downloadFileCbFun = std::bind(&HttpExample::handleHttpDownloadFile, this, std::placeholders::_1);
    _httpServer->addChunkHttpApi("/whttpserver/downloadFile/", downloadFileCbFun, W_HTTP_GET | W_HTTP_HEAD);
}

在main函数中启动发动机:

while(true)
{
    httpTest.run();
}

http接口回调示例代码:

void HttpExample::handleHttpRequestTest(shared_ptr<HttpReqMsg> &httpMsg)
{
    // You can add http headers like below
    stringstream sstream;
    sstream << "Access-Control-Allow-Origin: *" << "\r\n";
    _httpServer->httpReplyJson(httpMsg, 200, sstream.str(), _httpServer->formJsonBody(0, "success"));
    // _httpServer->httpReplyJson(httpMsg, 200, "", _httpServer->formJsonBody(0, "success"));
}
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 18:20:11  更:2022-04-18 18:20:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:19:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码