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

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;//用户idss_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.hqwc.cn/news/60367.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Golang bitset 基本使用

安装&#xff1a; go get github.com/bits-and-blooms/bitset下面代码把fmtx换成fmt就行 //------------基本操作------------//构建一个64bit长度的bitsetb : bitset.New(64)//放入一个数b.Set(10)fmtx.Println("add-10&#xff1a;", b.DumpAsBits()) // 0000000…

MyBatisX自动和数据库的字段关联

先下个插件 右键数据库&#xff0c;点MybatisX-Generator 在根据自己需求勾选 actual column&#xff1a;保证数据库的驼峰命名生效

idea模板的使用(配置xml文件模板)

1. 问题的引出 我们在日常项目中可以发现&#xff0c;sql映射文件和mybatis主配置文件&#xff0c;以及application.yml文件中有很多固定不变的内容&#xff0c;为了方面使用&#xff0c;所以可以把这些xml文件设置为模板 2. 创建模板的步骤 按照图片一步一步进行即可 点击…

JavaScript之事件的转控、反控、函数式编程

文章目录 效果图htmlJavaScript解析 效果图 html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>函…

基于亚奈奎斯特采样和SOMP算法的平板脉冲响应空间插值matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ...................................................................... %fine regular gr…

【人工智能前沿弄潮】—— 玩转SAM(Segment Anything)

玩转SAM(Segment Anything) 官网链接&#xff1a; Segment Anything | Meta AI (segment-anything.com) github链接&#xff1a; facebookresearch/segment-anything: The repository provides code for running inference with the SegmentAnything Model (SAM), links fo…

基于微信小程序的传染病酒店隔离平台设计与实现(Java+spring boot+MySQL+微信小程序)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于微信小程序的传染病酒店隔离平台设计与实现&#xff08;Javaspring bootMySQL微信小程序&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;…

业绩难言乐观,皓泽电子撤回上市申请,小米等为其关联方

撰稿|行星 来源|贝多财经 8月8日&#xff0c;深圳证券交易所披露的信息显示&#xff0c;由于河南皓泽电子股份有限公司&#xff08;下称“皓泽电子”&#xff09;及其保荐人主动要求撤回申请文件&#xff0c;深交所终止了皓泽电子的发行注册程序。 据此前招股书披露&#xff…

实战:使用Docker部署Hadoop集群

文章目录 Hadoop简介Hadoop优势Hadoop应用场景docker与docker-compose安装Hadoop集群搭建环境变量docker-compose环境文件树结构编排并运行容器运行wordcount例子 写在最后 Hadoop简介 Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节…

企业在线产品手册可以这样做,小白也能轻松上手

企业在线产品手册是为了方便用户了解和使用企业产品而设计的一种在线文档。它的目标是提供清晰、简洁、易于理解的产品信息&#xff0c;使用户能够轻松上手&#xff0c;并最大限度地发挥产品的功能和优势。 如何设计企业在线产品手册的建议和步骤&#xff1a; 目标用户分析&am…

灰度非线性变换之c++实现(qt + 不调包)

本章介绍灰度非线性变换&#xff0c;具体内容包括&#xff1a;对数变换、幂次变换、指数变换。他们的共同特点是使用非线性变换关系式进行图像变换。 1.灰度对数变换 变换公式&#xff1a;y a log(1x) / b&#xff0c;其中&#xff0c;a控制曲线的垂直移量&#xff1b;b为正…

纯跟踪(Pure Pursuit)路径跟踪算法研究(2)

纯跟踪(Pure Pursuit)路径跟踪算法研究&#xff08;2&#xff09; 下午进行了简单的公式推导&#xff0c;理论推导部分是没有问题的 下面的博客提供了在实车上用 GPS 实现纯跟踪控制的一些思路和注意点 Pure Pursuit&#xff08;纯追踪算法&#xff09;ROS实践 并不急于在实车…