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