【sylar】框架篇-Chapter17-HttpServer 模块

站在巨人的肩膀上

C++高性能分布式服务器框架

从零开始重写sylar C++高性能分布式服务器框架

概述

  • Http 服务器的封装。

HttpServer

  • HttpServer 封装类。
  • 继承自 TcpServer。
  • 内含 Servlet 分发器(可设置、可获取)。
  • 重写了 TcpServer 的 handleClient 方法。

接收请求和发送响应的数据流转

new sylar::http::HttpServer
		↓
HttpServer::bind (socket bind 和 listen)
		↓
HttpServer::start (放入调度器 accept)
		↓
收到请求:HttpServer::handleClient,创建 HttpSession
		↓
在HttpSession::recvRequest() 读取报文(其实是从 SocketStream 读的)
		↓
用 HttpRequestParser 解析报文并组装得到 HttpRequest
		↓
创建 HttpResponse,并把 HttpRequest、HttpResponse、HttpSession 一并交给 ServletDispatch 去处理

ServletDispatch 根据HttpRequest 的 path 匹配最佳的 Servlet 进行处理
		↓
Servlet 的处理是设置 HttpResponse 的一些内容(也就是响应报文))
		↓
ServletDispatch 处理完,HttpSession 将 HttpResponse 发出去(数据传给 Stream- > SocketStream,最后通过 socket send 出去,socket 的 send 是 hook 过的)

部分相关代码

/**
 * @filename    http_server.h
 * @brief   Http服务器的封装
 * @author  L-ge
 * @version 0.1
 * @modify  2022-07-16
 */
#ifndef __SYLAR_HTTP_HTTP_SERVER_H
#define __SYLAR_HTTP_HTTP_SERVER_H

#include "sylar/tcp_server.h"
#include "http_session.h"
#include "servlet.h"

namespace sylar
{

namespace http
{

class HttpServer : public TcpServer
{
public:
    typedef std::shared_ptr<HttpServer> ptr;

    /**
     * @brief   构造函数
     *
     * @param   keepalive   是否长连接
     * @param   worker      工作调度器
     * @param   io_worker
     * @param   accept_worker   接收连接的调度器
     */
    HttpServer(bool keepalive = false
             , sylar::IOManager* worker = sylar::IOManager::GetThis()
             , sylar::IOManager* io_worker = sylar::IOManager::GetThis()
             , sylar::IOManager* accept_worker = sylar::IOManager::GetThis());

    /**
     * @brief   获取ServletDispatch
     */
    ServletDispatch::ptr getServletDispatch() const { return m_dispatch; }

    /**
     * @brief   设置ServletDispatch 
     */
    void setServletDispatch(ServletDispatch::ptr v) { m_dispatch = v; }

    virtual void setName(const std::string& v) override;

protected:
    virtual void handleClient(Socket::ptr client) override;

private:
    /// 是否支持长连接
    bool m_isKeepalive;
    /// Servlet分发器
    ServletDispatch::ptr m_dispatch;
};

}

}

#endif


#include "http_server.h"
#include "sylar/log.h"
//#include "sylar/http/servlets/config_servlet.h"
//#include "sylar/http/servlets/status_servlet.h"

namespace sylar
{

static sylar::Logger::ptr g_logger = SYLAR_LOG_NAME("system");

namespace http
{

HttpServer::HttpServer(bool keepalive
                     , sylar::IOManager* worker
                     , sylar::IOManager* io_worker
                     , sylar::IOManager* accept_worker)
    : TcpServer(worker, io_worker, accept_worker)
    , m_isKeepalive(keepalive)
{
    m_dispatch.reset(new ServletDispatch);

    m_type = "http";
    //m_dispatch->addServlet("/_/status", Servlet::ptr(new StatusServlet));
    //m_dispatch->addServlet("/_/config", Servlet::ptr(new ConfigServlet));
}

void HttpServer::setName(const std::string& v)
{
    TcpServer::setName(v);
    m_dispatch->setDefault(std::make_shared<NotFoundServlet>(v));
}

void HttpServer::handleClient(Socket::ptr client)
{
    SYLAR_LOG_DEBUG(g_logger) << "handleClient " << *client;
    HttpSession::ptr session(new HttpSession(client));
    do
    {
        auto req = session->recvRequest();
        if(!req)
        {
            SYLAR_LOG_DEBUG(g_logger) << "recv http request fail, errno="
                << errno << " errstr=" << strerror(errno)
                << " client:" << *client << " keep_alive=" << m_isKeepalive;
            break;
        }

        HttpResponse::ptr rsp(new HttpResponse(req->getVersion()
                    , req->isClose() || !m_isKeepalive));
        rsp->setHeader("Server", getName());
        m_dispatch->handle(req, rsp, session);  // 交给ServletDispatch处理
        session->sendResponse(rsp);

        if(!m_isKeepalive || req->isClose())
        {
            break;
        }
    } while(true);

    session->close();
}

}

}

广告时间:基于sylar框架实现的小demo(希望给个star)

基于redis的参数查询服务

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值