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

brynet源码阅读——http组件和wrapper组件

0、引言

在前面的文章中介绍了brynet网络库中的各个组件,在这篇文章中介绍wrapper组件和http组件。其中wrapper组件是给用户使用使用的封装接口,用户只需要简单设置一些参数就可以搭建一个网络服务器或者客户端。而http组件是brynet中http部分的关键部分,依赖于开源的http_parser.h模块。

1、wrapper组件

1.1、ConnectionBuilder.hpp

该文件中封装了建立会话连接的Builder器,提供了一些简单的接口,用来给用户设置一些配置,设置完了配置可以直接调用asyncConnect启动连接。示例代码如下:

wrapper::ConnectionBuilder connectionBuilder;
    connectionBuilder
            .WithService(service)
            .WithConnector(connector)
            .WithMaxRecvBufferSize(1024 * 1024)
            .AddEnterCallback(enterCallback);

1.2、HttpConnectionBuilder.hpp

这个类在ConnectionBuilder的基础上封装了一个专门用做Http会话连接的Builder类,看懂了ConnectionBuilder.hpp中的实现,这个文件中的类就是又封装了一层,比较简单。使用方法如下:

 wrapper::HttpConnectionBuilder()
                .WithConnector(connector)
                .WithService(service)
                .WithAddr("14.215.177.39", 80)
                .WithTimeout(std::chrono::seconds(10))
                .WithFailedCallback([]() {
                    std::cout << "connect failed" << std::endl;
                })
                .WithMaxRecvBufferSize(1000)
                .WithEnterCallback([requestStr](const HttpSession::Ptr& session, HttpSessionHandlers& handlers) {
                    (void) session;
                    std::cout << "connect success" << std::endl;
                    session->send(requestStr);
                    handlers.setHttpBodyCallback([](const HTTPParser& httpParser,
                                                    const HttpSession::Ptr& session,
                                                    const char* body,
                                                    size_t length) {
                        (void) httpParser;
                        (void) session;
                        (void) body;
                        (void) length;
                    });
                    handlers.setHeaderCallback([](const HTTPParser& httpParser,
                                                  const HttpSession::Ptr& session) {
                        (void) httpParser;
                        (void) session;
                    });
                    handlers.setHttpEndCallback([](const HTTPParser& httpParser,
                                                   const HttpSession::Ptr& session) {
                        (void) session;
                        // because has call setHttpBodyCallback, so the body from http parser is empty.
                        std::cout << httpParser.getBody() << std::endl;
                        counter.fetch_add(1);
                        std::cout << "counter:" << counter.load() << std::endl;
                        session->postClose();
                    });
                })
                .asyncConnect();

1.3、HttpServiceBuilder.hpp

在ListenerBuilder的基础上封装了一层专门建立HttpService的Build器,只要理解了ListenerBuilder的原理,这里的代码非常简单。使用方法如下:

wrapper::HttpListenerBuilder listenBuilder;
    listenBuilder
            .WithService(service)
            .AddSocketProcess([](TcpSocket& socket) {
                socket.setNodelay();
            })
            .WithMaxRecvBufferSize(1024)
            .WithAddr(false, "0.0.0.0", port)
            .WithReusePort()
            .WithEnterCallback([httpEnterCallback, wsEnterCallback](const HttpSession::Ptr& httpSession, HttpSessionHandlers& handlers) {
                handlers.setHttpEndCallback(httpEnterCallback);
                handlers.setWSCallback(wsEnterCallback);
            })
            .asyncRun();

1.4、ServiceBuilder.hpp

该文件中定义了建立服务的Builder类,监听线程和工作线程可以是1:1,也可以是1:n,这取决于mTcpService指向对象的类型,关键的成员函数理解如下:

// 服务器中真正的worker service,这里面都是监听的通信socket
ITcpService::Ptr mTcpService;
// 会话建立成功需要执行的callback
std::vector<ListenThread::TcpSocketProcessCallback> mSocketProcessCallbacks;
// 建立会话的参数
ConnectionOption mSocketOption;
// 监听的ip地址
std::string mListenAddr;
// 监听的端口
int mPort = 0;
bool mIsIpV6 = false;
bool mEnabledReusePort = false;
// 监听线程
ListenThread::Ptr mListenThread;

2、http组件

2.1、http_parser.h

这部分是开源的库,用来解析Http的请求命令和响应命令,这部分代码还没有仔细研究,使用方法和其他的库类似,都是通过一些callback将解析到的数据保存到自己定义的数据结构中。

2.2、HttpFormat.hpp

该文件中定义了两个关键类,一个是HttpRequest、一个是HttpResponse。其中HttpRequest是Http请求的结构体,在发送请求之前,创建一个对象,并通过提供的接口设置参数,最后通过getResult() 接口获得Http请求指令的字符串,这样就可以通过通信套接字发送出去。同理,HttpResponse是响应的Http指令。网络库中定义这两个类是常见做法。

2.3、HttpParser.hpp

该文件中定义了HTTPParser类,http解析类,借助开源的http_parser.h,核心思想是将接收到的字符串利用http_parser.h将其解析并将解析出来的内容利用callback的形式放到类的成员变量中,并且会执行对应的callback函数。brynet在制作返回的HttpResponse时是在callback函数中做的,并不像sylar框架那样,callback中只将命令分解出来,真正的做请求响应动作是在serverlet中做的。下面介绍下各个成员变量的含义:

// http_parser中的数据结构
const http_parser_type mParserType;
http_parser mParser;
// 解析的时候用到的callback
http_parser_settings mSettings;
// 方法
int mMethod = -1;
bool mIsUpgrade = false;
bool mIsWebSocket = false;
// 链接是否alive
bool mIsKeepAlive;
// 解析是否结束
bool mISCompleted;
// 下面这些成员变量主要用于存储解析出来的数据
std::string mPath;
std::string mQuery;
std::string mStatus;
std::map<std::string, std::string> mHeadValues;
int mStatusCode;
// 存放解析出来的url、body
std::string mUrl;
std::string mBody;
// websocket相关的
std::string mWSCacheFrame;
std::string mWSParsePayload;
WebSocketFormat::WebSocketFrameType mWSFrameType;
// 解析完头需要执行的callback
std::function<void()> mHeaderCallback;
// 解析完body需要执行的callback
std::function<void(const char*, size_t)> mBodyCallback;
// 解析完成需要执行的callback,可以将HttpResponse的拼装放到这里面做
std::function<void()> mMsgEndCallback;

2.4、HttpService.hpp

该文件中定义了3个类,Http会话类HttpSession、Http会话类相关的callback函数和HttpService类。HttpService类中的关键函数代码如下

static void setup(const TcpConnection::Ptr& session,
                      const HttpSession::EnterCallback& enterCallback)
{
    if (enterCallback == nullptr)
    {
        throw BrynetCommonException("not setting http enter callback");
    }

    auto httpParser = std::make_shared<HTTPParser>(HTTP_BOTH);
    auto httpSession = HttpSession::Create(session);

    HttpSessionHandlers handlers;
    // 这里一般会往handlers中设置一些回调函数,等到解析器解析到对应的数据后,才会执行对应的callback函数
    enterCallback(httpSession, handlers);
    httpSession->setClosedCallback(std::move(handlers.mCloseCallback));
    httpSession->setWSCallback(std::move(handlers.mWSCallback));
    httpSession->setWSConnected(std::move(handlers.mWSConnectedCallback));
    // 设置callback到httpParser
    auto headerCB = handlers.mHttpHeaderCallback;
    if (headerCB != nullptr)
    {
        httpParser->setHeaderCallback([=]() {
            headerCB(*httpParser, httpSession);
        });
    }

    auto bodyCB = handlers.mHttpBodyCallback;
    if (bodyCB != nullptr)
    {
        httpParser->setBodyCallback([=](const char* body, size_t length) {
            bodyCB(*httpParser, httpSession, body, length);
        });
    }
    // 一般在这里的callback会组装HttpResponse
    auto endCB = handlers.mHttpEndCallback;
    if (endCB != nullptr)
    {
        httpParser->setEndCallback([=]() {
            endCB(*httpParser, httpSession);
        });
    }
    // 这里也是设置callback函数
    HttpService::handle(httpSession, httpParser);
}

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

相关文章:

  • 瑞芯微方案主板Linux修改系统串口波特率教程,触觉智能RK3562开发板演示
  • wordpress网站首页底部栏显示网站备案信息
  • 【Linux课程学习】:站在文件系统之上理解:软硬链接,软硬链接的区别
  • Web day07 项目实战
  • Python学习38天
  • 【Pytorch】torch.view与torch.reshape的区别
  • Reinforcement Learning with Human in the Loop Human Feedback
  • 【漏洞复现】海信智能公交企业管理系统 apply.aspx SQL注入漏洞
  • SIMD与SIMT
  • 刷leetcode hot100--3贪心(30min,看思路)
  • 【数据结构】【线性表】特殊的线性表-字符串
  • Android中使用NSD扫描,实现局域网内设备IP的发现
  • 第1章:CSS简介 --[CSS零基础入门]
  • Scala 的match case 匹配元组
  • zerotier实现内网穿透
  • M31系列LoRa分布式IO模块功能简介
  • 黑马2024AI+JavaWeb开发入门Day04-SpringBootWeb入门-HTTP协议-分层解耦-IOCDI飞书作业
  • 【微服务】SpringBoot 对接飞书多维表格事件回调监听流程详解
  • 基于Linux的逻辑订阅发布搭建
  • 多线程运行时,JVM(Java虚拟机)的内存模型
  • Runway 技术浅析(七):视频技术中的运动跟踪
  • [TLS] 使用 OpenSSL 命令行测试 TLS13 0-RTT
  • 关于机器学习领域的预测算法/模型基础入门
  • 【论文笔记】Frequency Domain Model Augmentation for Adversarial Attack
  • BioDeepAV:一个多模态基准数据集,包含超过1600个深度伪造视频,用于评估深度伪造检测器在面对未知生成器时的性能。
  • 【ETCD】ETCD用户密码认证