Session的適用性很廣,翻譯為‘會話’,最初接觸他的時候在做web方面,可以記錄一個用戶的會話記錄,當關閉瀏覽器的時候失效!Session實際上是一個特定的時間概念.
在最開始接觸它時沒有刻意的研究實現與擴展性,然后最近的一個工程有這樣的一個功能,就是統計最近5分鐘的流量。其實完全可以設計一個Session來記錄當前的流量,然后設置超過5分鐘后的流量自動釋放。
感覺起來像一個定時器,其實可以設置每個數據包的超時時間,即會話時間(Session),然后自動釋放與自動增加。
下面是實現代碼:
1
#pragma once
2
3
/**////////////////////////////////////////////////// 4
//! 會話Session記錄模板
5
/**////////////////////////////////////////////////// 6
7
#include <list>
8
using namespace std;
9
10
#define MAXTIME 1<<32
11
#define FLAGLAY true
12
13
template<class Sessinfo>
14
class Session
15

{
16
17
public:
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
44
public:
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
138
protected:
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
156
private:
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
173
template<class Sessinfo>
174
ostream & 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
/**/////////////////////////////////////////////////188
template<>
189
class 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>
7
using namespace std;
8
9
#define TIMER 5 // 10秒鐘 5分鐘
10
11
struct TData
12

{
13
int data;
14
long time;
15
}; // 數據包
16
bool comp (const TData & _data , const TData & _tdata)
17

{
18
return ( (_tdata.data == _data.data) && (_tdata.time == _data.time));
19
}
20
21
int _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