勤能补拙,Expter

成都游戏Coder,记录游戏开发过程的笔记和心得!

关于会话记录Session的实现

       Session的适用性很广,翻译为‘会话’,最初接触他的时候在做web方面,可以记录一个用户的会话记录,当关闭浏览器的时候失效!Session实际上是一个特定的时间概念.

      在最开始接触它时没有刻意的研究实现与扩展性,然后最近的一个工程有这样的一个功能,就是统计最近5分钟的流量。其实完全可以设计一个Session来记录当前的流量,然后设置超过5分钟后的流量自动释放。

       感觉起来像一个定时器,其实可以设置每个数据包的超时时间,即会话时间(Session),然后自动释放与自动增加。

下面是实现代码:
  1#pragma once
  2
  3/////////////////////////////////////////////////
  4//! 会话Session记录模板
  5/////////////////////////////////////////////////
  6
  7#include <list>
  8using namespace std;
  9
 10#define  MAXTIME     1<<32
 11#define  FLAGLAY     true
 12
 13template<class Sessinfo>
 14class Session
 15{
 16
 17public:
 18
 19    // 默认构造函数
 20    Session()
 21        :M_lMaxHoldTime(MAXTIME)
 22        ,M_bAllowOverlay(FLAGLAY)
 23    {}
 24
 25    // 构造函数
 26    Session(long MaxTime , bool bAllOverlay =  true)
 27        :M_lMaxHoldTime(MaxTime)
 28        ,M_bAllowOverlay(bAllOverlay)
 29    {}
 30
 31    // 只有一个会话记录
 32    static Session   *Getinstance()
 33    {
 34        if( instance == NULL )
 35        {
 36           instance = new Session();
 37        }

 38        return instance;
 39    }

 40
 41    virtual ~Session(){}
 42
 43
 44public:
 45    // 增加一个新的会话
 46    // 如果不想使用构造时定义的有效保持时间,可以根据用户
 47    // 返回增加失败与成功否。
 48
 49    bool AddSession(const Sessinfo &Info , int HoldTime = 0)
 50    {
 51        // 清理超时会话
 52        long Now_time = time(NULL);
 53        DealOutTime(Now_time);   
 54
 55        // 查找某个值,然后进行操作
 56        for(list<ESession>::iterator it =Mlist_Session.begin() ; it != Mlist_Session.end();it++)
 57        {    
 58            if( comp(it->ENode , Info))
 59            {
 60                if(M_bAllowOverlay)     
 61                {
 62                    it = Mlist_Session.erase(it);
 63                    break;
 64                }

 65                else
 66                {
 67                    return false;
 68                }

 69            }

 70        }

 71        // 创建一个新的节点
 72        ESession NewSession;
 73        NewSession.ENode = Info;
 74        if(HoldTime != 0)
 75            NewSession.SEndTime = Now_time + HoldTime;
 76        else
 77            NewSession.SEndTime = Now_time + M_lMaxHoldTime;
 78
 79        // 如果没有等待时间,表示处于长等状态
 80        if(HoldTime != 0)
 81        {
 82            for(list<ESession>::iterator ite =Mlist_Session.begin(); ite !=Mlist_Session.end(); ite++)
 83            {
 84                if(ite->SEndTime > NewSession.SEndTime )
 85                {
 86                    if( Mlist_Session.begin() == ite)
 87                    {
 88                        Mlist_Session.push_front(NewSession);
 89                    }

 90                    else
 91                    {
 92                        Mlist_Session.insert(--ite,NewSession);
 93                    }

 94                    return true;
 95                }

 96            }

 97        }
    
 98        Mlist_Session.push_back(NewSession);
 99        return true;
100    }

101
102    // 验证一个拷贝会话,
103    // 验证一个会话,完成后是否删除
104    bool TestCopySession(const Sessinfo & Info, bool bRemove = true)
105    {
106        // 清理超时会话
107        long Now_time = time(NULL);
108        DealOutTime(Now_time);   
109
110        // 查找某个值,然后进行操作
111        for(list<ESession>::iterator it =Mlist_Session.begin() ; it != Mlist_Session.end(); it++)
112        {    
113            if(it->ENode == Info)
114            {
115                memmove(&Info,&(it->ENode),sizeof(Session));
116                if(bRemove)     
117                {
118                    it = Mlist_Session.erase(it);
119                    return true;
120                }

121            }

122        }

123        return false;
124    }

125    
126    void Run_ForEach(void (*Fun)(Sessinfo &,void *),void * lparam)
127    {
128        DealOutTime(time(NULL));
129        
130        for(list<ESession>::iterator it =Mlist_Session.begin() ; it != Mlist_Session.end(); it++)
131        {
132            (*Fun)(it->ENode,lparam);
133        }

134    }

135
136    friend ostream & operator << <>(ostream &out , const Session<Sessinfo> &sess);
137
138protected:
139    // 处理以及超时的结点,然后删除
140    void  DealOutTime(long Now_time)
141    {
142        // Mlist_Session有序列表,结束时间从前向后排列,
143        for(list<ESession>::iterator it=Mlist_Session.begin(); it != Mlist_Session.end(); )
144        {
145            if(it->SEndTime < Now_time)
146            {
147                it = Mlist_Session.erase(it);
148            }

149            else
150            {
151                return ;
152            }

153        }

154    }

155    
156private:
157    
158    // 会话元素
159    struct ESession
160    {
161        long        SEndTime;// 会话结束时间      
162        Sessinfo    ENode;   // 会话节点
163    }
;
164    
165    list<ESession>  Mlist_Session;          //   保存的会话元素的链表
166    long            M_lMaxHoldTime;            //   最大会话时间(秒),通过time来得到
167    bool            M_bAllowOverlay;        //   创建的会话已存在的时候时候覆盖。
168    
169
170    static Session  *instance;
171}
;
172
173template<class Sessinfo>
174ostream & operator << (ostream &out , const Session<Sessinfo> &sess)
175{
176    for(list<Session<Sessinfo>::ESession>::const_iterator it = sess.Mlist_Session.begin() ; it != sess.Mlist_Session.end(); it++)
177    {
178        cout << *((int*)&(it->ENode)) <<" = "<< *(((int*)&(it->ENode))+1<<endl;
179    }

180    cout <<" ----------------------------------"<<endl;
181    return out;
182}

183
184
185/////////////////////////////////////////////////
186//! 会话Session类特化
187////////////////////////////////////////////////
188template<>
189class Session<int>
190{
191
192
193}
;

写的一个实现代码:
 1// MySession.cpp : 定义控制台应用程序的入口点。
 2#include "Session.h"
 3#include <ctime>
 4#include <map>
 5#include <iostream>
 6#include <windows.h>
 7using namespace std;
 8
 9#define TIMER    5         // 10秒钟 5分钟
10
11struct TData
12{
13    int  data;
14    long time;
15}
;                     // 数据包
16bool comp (const TData & _data , const TData & _tdata)
17{
18    return ( (_tdata.data == _data.data) && (_tdata.time == _data.time));
19}

20
21int _tmain(int argc, _TCHAR* argv[])
22{
23    Session<TData>  Sess(TIMER);
24    
25    for(int count = 0 ; count < 20 ; count ++)
26    {
27        TData tmp;
28        tmp.data = count +1;
29        tmp.time = time(NULL);
30        Sess.AddSession(tmp,TIMER);
31        cout << Sess <<endl;
32        Sleep(500);
33    }

34    return 0;
35}

36
37

posted on 2009-04-22 20:53 expter 阅读(1421) 评论(1)  编辑 收藏 引用 所属分类: 其他学习笔记工作笔记算法与数据结构

评论

# re: 关于会话记录Session的实现 2009-04-28 13:30 guest

其实session在实际的开发中 运用非常广。。
封装好了很方便的,  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理