Consolexin's blog Consolexin's blog
首页
  • 算法基础

    • 图论
    • 字符串
    • 动态规划
    • 二分
    • 滑动窗口
    • 排序
  • Project

    • CppServer
  • 相关书籍

    • 现代C++编程
  • 书籍

    • SQL必知必会
    • MySQL必知必会
分类
标签
归档
GitHub (opens new window)

Consolexinhun

小学生
首页
  • 算法基础

    • 图论
    • 字符串
    • 动态规划
    • 二分
    • 滑动窗口
    • 排序
  • Project

    • CppServer
  • 相关书籍

    • 现代C++编程
  • 书籍

    • SQL必知必会
    • MySQL必知必会
分类
标签
归档
GitHub (opens new window)
  • README
  • day01-从一个最简单的socket开始
  • day02-不要放过任何一个错误
  • day03-高并发还得用epoll
  • day04-来看看我们的第一个类
  • day05-epoll高级用法-Channel登场
  • day06-服务器与事件驱动核心类登场
  • day07-为我们的服务器添加一个Acceptor
  • day08-一切皆是类,连TCP连接也不例外
  • day09-缓冲区-大作用
  • day10-加入线程池到服务器
  • day11-完善线程池,加入一个简单的测试程序
  • day12-将服务器改写为主从Reactor多线程模式
  • day13-支持业务逻辑自定义、完善Connection类
  • day14-重构核心库、使用智能指针
  • day15-重构Connection、修改生命周期
  • day16-使用CMake工程化
  • day17-使用EventLoopThreadPool、移交EventLoop
  • day18-HTTP有限状态转换机
  • day19-创建HTTP响应,实现HTTP服务器
  • day20-定时器的创建使用
  • day21-服务器主动关闭连接
  • day22-初步涉及日志库,定义自己的输出流LogStream
  • day23-定义前端日志库,实现同步输出
  • day24-异步日志库
  • day25-更有效的缓冲区
  • day26-监听写事件
  • day27-处理静态文件,实现POST请求
  • day28-文件服务器的简单实现,文件的展示和下载
  • day29-文件的上传
  • day30-WebBench的测试
  • CppServer
consolexinhun
2025-04-20

day21-服务器主动关闭连接

# day21-服务器主动关闭连接

在上一天实现了一个基础的定时器功能。考虑了半天,我似乎还没有学习到应用到定时器的场景。因此做了一个简单的应用,也就是服务器主动关闭连接,当某个连接连接时间过长时,则服务端将主动关闭连接。

这个功能实现起来并不复杂,首先,在服务端创建连接回调时,加入一个RunAfter事务,这个函数将服务端关闭连接的函数传入,当距离上一个上一次活跃时间间隔autoclosetimeout时,则尝试关闭连接。

void HttpServer::onConnection(const TcpConnectionPtr &conn){
    if(auto_close_conn_){
        loop_->RunAfter(AUTOCLOSETIMEOUT, std::move(std::bind(&HttpServer::ActiveCloseConn, this, std::weak_ptr<TcpConnection>(conn))));
    }
}
1
2
3
4
5

服务端关闭时,将计算当前时间距离当前连接conn上一次活跃的时间是否满足定义的自动断开的时长,如果是,则直接关闭,如果不是,则重新加入RunAfter事务,我们在主动释放连接时,并不需要去管理connection的生命周期,而是简单的使用它,因此采用了weak_ptr作为参数。

void HttpServer::ActiveCloseConn(std::weak_ptr<TcpConnection> & connection){
    TcpConnectionPtr conn = connection.lock(); // 防止conn已经被释放
    if (conn)
    {
        if(TimeStamp::AddTime(conn->timestamp(), AUTOCLOSETIMEOUT) < TimeStamp::Now()){
            conn->Shutdown();
        }else{
            loop_->RunAfter(AUTOCLOSETIMEOUT, std::move(std::bind(&HttpServer::ActiveCloseConn, this, connection)));
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11

为了保存TCP连接的时长,则为TcpConnection增加一个TimeStamp成员变量保存当前连接的最后一次活跃时间,并在每次客户端与服务端进行交互时,将TimeStamp进行更新。

void HttpServer::onMessage(const TcpConnectionPtr &conn){
    if (conn->state() == TcpConnection::ConnectionState::Connected)
    {
        if(auto_close_conn_)
            conn->UpdateTimeStamp(TimeStamp::Now());
        // ...
    }
}
1
2
3
4
5
6
7
8

这只是一个简单的定时器的应用,此外还有许多应用场景,但是并不在本文中赘述。

编辑 (opens new window)
上次更新: 2025/05/21, 06:42:57
day20-定时器的创建使用
day22-初步涉及日志库,定义自己的输出流LogStream

← day20-定时器的创建使用 day22-初步涉及日志库,定义自己的输出流LogStream→

最近更新
01
6-其他操作
05-20
02
4-联结
05-20
03
7-管理
05-20
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Consolexinhun | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×