C++项目:在线五子棋对战网页版--session管理模块开发

news2024/11/15 21:24:48

session 

在WEB开发中,HTTP协议是⼀种⽆状态短链接的协议,这就导致⼀个客⼾端连接到服务器上之后,服务器不知道当前的连接对应的是哪个用户,也不知道客⼾端是否登录成功,这时候为客⼾端提所有服务是不合理的。因此,服务器为每个用户浏览器创建⼀个会话对象(session对象),注意:⼀个浏览器独占⼀个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使⽤浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,识别该连接对应的用户,并为用户提供服务。

这⾥简单设计⼀个session类,但是session对象不能⼀直存在,这样是⼀种资源泄漏,因此需要使⽤定时器对每个创建的session对象进⾏定时销毁(⼀个客⼾端连接断开后,⼀段时间内都没有重新连接则销毁session)。

session类

对于一个用户独占的session来说,需要有session的一个id,也就是标识符,需要对于的用户id,登录状态,以及session需要用到的定时器。

session类需要提供设置session状态,设置用户id和定时器的方法,需要提供给外界获取session标识符,用户id和定时器的方法,需要提供判断session是否处于登录状态的方法。

typedef enum {UNLOGIN, LOGIN} ss_statu;
class session
{
private:
    uint64_t _ssid;//session标识符
    uint64_t _uid;//用户id
    ss_statu _statu;//用户状态:未登录,已登录
    wsserver_t::timer_ptr _tp;//session关联的定时器
public:
    session(uint64_t ssid): _ssid(ssid){ DLOG("SESSION %p 被创建!!", this); }
    ~session() { DLOG("SESSION %p 被释放!!", this); }
    
    uint64_t ssid(){return _ssid;}/*获取session的标识符*/
    uint64_t get_user(){return _uid;}/*获取用户id*/
    wsserver_t::timer_ptr& get_timer() { return _tp; }/*获取定时器*/

    void set_statu(ss_statu statu){_statu = statu;}/*设置session的状态*/
    void set_user(uint64_t uid){_uid = uid;}/*设置session的用户id*/
    void set_timer(wsserver_t::timer_ptr& tp){_tp = tp};/*设置定时器*/

    bool is_login(){return (_statu == LOGIN);}/*判断是否处于登录状态*/

};

session管理类

将session类实现好之后,接下来就是需要将session统一管理起来了。

在session管理类中,需要对每一个session进行编号,而这个编号,就是session的标识符ssid,是不能乱编,为了避免session编号出现错误,因此采用计数器的方式,并且将session交由智能指针shared_ptr去管理,这样就方便进行操作了。

在session管理类中,主要实现这些方法:

创建session、通过ssid获取session、通过ssid判断session是否存在、销毁session和为session设置过期时间,过期后session被销毁。

using session_ptr = std::shared_ptr<session>;
#define SESSION_TIMEOUT 300000
#define SESSION_FOREVER -1
class session_manager
{
private:
    uint64_t _next_ssid;
    std::mutex _mutex;
    std::unordered_map<uint64_t,session_ptr> _session;
    wsserver_t * _server;
public:
    session_manager(wsserver_t *srv)
        :_next_ssid(1)
        ,_server(srv)
    {
        DLOG("session管理器初始化完毕!");
    }
    ~session_manager()
    {
        DLOG("session管理器即将销毁!");
    }
    /*创建session*/
    session_ptr create_session(uint64_t uid, ss_statu statu)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        /*创建出一个新的session,通过智能指针管理*/
        session_ptr ssp(new session(_next_ssid));
        /*设置session的状态、用户id*/
        ssp->set_statu(statu);
        ssp->set_user(uid);
        /*将session的智能指针与session的ssid建立映射关系*/
        _session.insert(std::make_pair(_next_ssid,ssp));
        _next_ssid++;
        return ssp;
    }

    /*将ssp进行管理*/
    void append_session(const session_ptr &ssp)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _session.insert(std::make_pair(ssp->ssid(),ssp));
    }

    /*通过ssid获取session信息*/
    session_ptr get_session_by_ssid(uint64_t ssid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _session.find(ssid);
        if(it==_session.end())
        {
            return session_ptr();
        }
        return it->second;
    }

    /*销毁session*/
    void remove_session(uint64_t ssid) 
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _session.erase(ssid);
    }

    /*为ssid对应的session设置生命周期*/
    void set_session_expire_time(uint64_t ssid, int ms)
    {
        //依赖于websocketpp的定时器来完成session生命周期的管理。
        //登录之后,创建session,session需要在指定时间无通信后删除
        // 但是进入游戏大厅,或者游戏房间,这个session就应该永久存在
        // 等到退出游戏大厅,或者游戏房间,这个session应该被重新设置为临时,在长时间无通信后被删除

        /*首先通过ssid获取session信息*/
        session_ptr ssp = get_session_by_ssid(ssid);
        if (ssp.get() == nullptr) 
        {
            return;
        }
        /*获取session中的定时器*/
        wsserver_t::timer_ptr tp = ssp->get_timer();
        /*根据情况进行设置*/
        /*1.在session永久存在的情况下,设置永久存在*/
        if(tp.get() == nullptr && ms == SESSION_FOREVER)
        {
            /*session本身就已经永久存在了*/
            return;
        }
        else if(tp.get() == nullptr && ms != SESSION_FOREVER)
        {
            /*在session永久存在的情况下,设置指定时间之后被删除的定时任务*/
            /*创建出一个临时的定时器,将该定时器设置为:过了ms的时间后,会调用remove_session函数进行session的销毁*/
            wsserver_t::timer_ptr tmp_tp = _server->set_timer(ms,std::bind(&session_manager::remove_session,this,ssid));
            ssp->set_timer(tmp_tp);/*设置进去*/
        }
        else if(tp.get() != nullptr && ms == SESSION_FOREVER)
        {
            //3. 在session设置了定时删除的情况下,将session设置为永久存在
            // 删除定时任务--- stready_timer删除定时任务会导致任务直接被执行
            tp->cancel();//因为这个取消定时任务并不是立即取消的
            //因此重新给session管理器中,添加一个session信息, 且添加的时候需要使用定时器,而不是立即添加
            ssp->set_timer(wsserver_t::timer_ptr());//将session关联的定时器设置为空
            _server->set_timer(0, std::bind(&session_manager::append_session, this, ssp));
        }
        else if(tp.get() != nullptr && ms != SESSION_FOREVER)
        {
            // 4. 在session设置了定时删除的情况下,将session重置删除时间。
                tp->cancel();//因为这个取消定时任务并不是立即取消的
                ssp->set_timer(wsserver_t::timer_ptr());
                _server->set_timer(0, std::bind(&session_manager::append_session, this, ssp));
                //重新给session添加定时销毁任务
                wsserver_t::timer_ptr tmp_tp  = _server->set_timer(ms, 
                    std::bind(&session_manager::remove_session, this, ssp->ssid()));
                //重新设置session关联的定时器
                ssp->set_timer(tmp_tp);
        }
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/855583.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信昵称后面的“小耳朵”,原来有这么多用处,让我带你涨知识

微信昵称后面的“小耳朵”&#xff0c;原来有这么多用处&#xff0c;让我带你涨知识 大家都知道&#xff0c;在微信昵称后面加上一个"小耳朵"符号是一种常见的表达方式&#xff0c;但你知道吗&#xff1f;这个看似简单的符号其实有着丰富的用处和意义。让我带你了解…

java中io流、属性集Properties、缓冲流、转换流、序列化和反序列化、打印流、网络编程(TCP通信程序、文件复制案例、文件上传案例、B/S服务案例)

IO流&#xff1a; io流中i表示input输入&#xff0c;o表示output输出&#xff0c;流表示数据&#xff08;字符&#xff0c;字节&#xff0c;1个字符2个字节8个位&#xff09;&#xff1b;这里的输入输出是以内存为基础&#xff0c;将数据从内存中输出到硬盘的过程称为输出&…

CMSIS—OS(V1/V2)

在RTOS基础上再封装一层API。 更换项目中所使用到的RTOS。 例如将freertos项目替换为ucos RTX liteos等其他RTOS。 只需更改该CMSIS-OS的API所调用的RTOS的API。 更换RTOS的意义何在&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&am…

函数的学习

函数学习 最后附上全部java源码&#xff0c;可自行下载学习 文章目录 函数入门函数重载函数可变个数参数foreach输出传参 基本数据类型传参_引用数据类型文件夹展示所有里面的文件使用递归算法展示文件夹下所有文件1加到100的递归调用下载链接 函数入门 函数重载 public class…

为什么企业一定要走标准化、体系化的道路?

企业实行标准化、体系化道路&#xff0c;有几个重要原因&#xff1a; 1.一致性和质量&#xff1a;标准化流程和系统可确保任务始终如一且高质量地执行。这种一致性对于提供满足客户期望的产品和服务至关重要&#xff0c;从而在客户之间建立信任和忠诚度。 2.效率和生产力&…

强化安全防线:迅软科技助力美容院提升终端安全管理水平

某美容院专注于皮肤抗衰老研究与美容领域服务,业务主要包含轮廊塑型、自体脂肪、五官雕塑等,业务涵盖中国、香港、美国、韩国等多个国家及地区提倡以积极、健康、理智的美学观点,以完善的美容院管理,过硬的技术设备,为消费者提供个性化漂亮服务。 美容院的核心诉求 美容院新产…

【攻防世界】command_execution

题目再现 小宁写了个ping功能,但没有写waf,X老师告诉她这是非常危险的&#xff0c;你知道为什么吗。 题目分析 本题目说没有写WAF&#xff0c;然后可以执行Linux经典代码PING&#xff0c;我猜测到服务器不会校验我所注入的代码&#xff0c;我利用串行执行符&&进行测…

查看CentOS版本及系统位数与设置CentOS 7.9 2009 防火墙配置放开端口的命令与过程

一、查看CentOS版本及系统位数 1.1 命令汇总 //1、安装redhat-lsb yum install -y redhat-lsb//2、查看系统版本信息 lsb_release -a //3、查看系统位数 getconf LONG_BIT1.2 截图 二、设置CentOS7.9 2009 防火墙配置放开端口 2.1 命令汇总 //禁止防火墙开机启动。这种方法方…

侯捷C++高级编程(下)

对于1个类要么像指针要么像函数 主题1:转换函数 转换函数 /** 1. 转换函数没有返回类型* 2. 转换函数一般需要加上const*/ class Fraction { public:Fraction(int num,int den1):m(num),n(den){cout<<"Fraction(int num,int den1): m/n "<< m/n<&…

[Leetcode - Python]704.二分查找(Easy)

1. 题目&#xff1a; 704.二分查找&#xff08;Easy&#xff09; 1代码&#xff1a; class Solution:def search(self, nums: List[int], target: int) -> int:left , right 0 ,len(nums)-1while left < right :mid (leftright)//2 # // 取整除&#xff0c;向…

Windows 安装 pandoc 将 jupyter 导出 pdf 文件

Windows 安装 pandoc 将 jupyter 导出 pdf 文件 1. 下载 pandoc 安装文件2. 安装 pandoc3. 安装 nbconvert4. 使用 pandoc 1. 下载 pandoc 安装文件 访问 https://github.com/jgm/pandoc/releases&#xff0c;下载最新版安装文件&#xff0c;例如&#xff0c;3.1.6.1 版&#…

【Kubernetes】Kubernetes之Pod详解

Pod 一、 Pod1. Pod 基础概念2. 在 Kubrenetes 集群中 Pod 使用方式2.1 pasue 容器2.2 kubernetes 中的 pause 容器提供的功能 3. Pod 的概念和结构组成4. Pod 的分类5. Pod 容器的分类5.1 基础容器&#xff08;infrastructure container&#xff09;5.2 初始化容器&#xff08…

【效率提升—Python脚本】根据Verilog文件自动生成tb文件

文章目录 Verilog端口文件&#xff08;仅做示范用&#xff09;对应的tb文件相应代码 在数字IC设计过程中&#xff0c;根据顶层生成testbench时存在很多重复性工作&#xff0c;因此为了提高工作效率&#xff0c;特地开发此脚本。 Verilog端口文件&#xff08;仅做示范用&#xf…

Centos7离线安装MySQL8

1、下载MySQL https://downloads.mysql.com/archives/community/ 2、下载完毕后&#xff0c;上传到Centos&#xff0c;解压 tar -xf mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar 3、逐条执行安装命令 rpm -ivh mysql-community-common-8.0.33-1.el7.x86_64.rpm rpm -ivh …

C++的vector

文章目录 迭代器失效问题构造函数赋值运算符begin() end()size() capacity() empty()reserve()operator[ ]insert()erase()resize() 迭代器失效问题 迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间 1.扩容导致迭代器失效问题 在对…

JVM工作的总体机制概述

JDK、JRE、JVM关系回顾 JVM&#xff1a;Java Virtual Machine&#xff0c;翻译过来是Java虚拟机JRE&#xff1a;Java Runtime Environment&#xff0c;翻译过来是Java运行时环境 JREJVMJava程序运行时所需要的类库JDK&#xff1a;Java Development Kits&#xff0c;翻译过来是…

数据结构【图的类型定义和存储结构】

数据结构之图 图的定义和概念图的定义图的术语 图的类型定义图的存储结构数组&#xff08;邻接矩阵&#xff09;表示法无向图的邻接矩阵表示法有向图的邻接矩阵表示法网&#xff08;即有权图&#xff09;的邻接矩阵表示法 邻接矩阵的ADT定义邻接表&#xff08;链式&#xff09;…

测试经典书籍拆分讲解

一、全程软件测试 测试行业的经典书籍 测试方法测试策略领域测试主流测试技术涵盖了软件测试的流程与方法体系 二、探索式测试 探索式测试的经典代表性书籍探索式测试是业务测试和手工测试实践中的一个方法论 三、Google测试之道 高级测试工程师与架构师必读讲解google的测…

(学习笔记-进程管理)进程间有哪些通信方式?

每个进程的用户地址空间都是独立的&#xff0c;一般而言是不能互相访问的&#xff0c;但内核空间时每个进程都共享的&#xff0c;所以进程之间要通信必须通过内核 管道 在Linux命令中 [ | ] 这个竖线就是一个管道。 $ ps auxf | grep mysql 它的功能是讲前一个命令&#xf…

8月9日上课内容 nginx负载均衡

负载均衡工作当中用的很多的&#xff0c;也是面试会问的很重要的一个点 负载均衡&#xff1a;通过反向代理来实现&#xff08;nginx只有反向代理才能做负载均衡&#xff09; 正向代理的配置方法&#xff08;用的较少&#xff09; 反向代理的方式&#xff1a;四层代理与七层代…