From 621186c27994dff0c1b3e0dfbc1d061b37e0cff5 Mon Sep 17 00:00:00 2001 From: xiemengjun Date: Tue, 25 Sep 2012 00:01:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BA=86=E5=86=85=E5=AD=98?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E7=9A=84=E4=B9=A6=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 6.3.md | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/6.3.md b/6.3.md index df207650..dbac572d 100644 --- a/6.3.md +++ b/6.3.md @@ -1,4 +1,119 @@ #6.3 session存储 +上一节我们介绍了Session管理器的实现原理,定义了如何实现session存储的接口,这小节我们讲通过一个例子来实现内存的session存储,其他类似数据库或者文件的存储,用户可以根据相应的接口定义来实现,内存的实现请看下面的例子代码 + + package memory + + import ( + "session/session" + "time" + ) + + var d = &Provider{} + + type SessionStore struct { + sid string //session id唯一标示 + timeAccessed time.Time //最后访问时间 + value map[interface{}]interface{} //session里面存储的值 + } + + func (this *SessionStore) Set(key, value interface{}) bool { + this.value[key] = value + d.SessionUpdate(this.sid) + return true + } + + func (this *SessionStore) Get(key interface{}) interface{} { + d.SessionUpdate(this.sid) + if v, ok := this.value[key]; ok { + return v + } else { + return "" + } + } + + func (this *SessionStore) Del(key interface{}) bool { + delete(this.value, key) + d.SessionUpdate(this.sid) + return true + } + + type Provider struct { + lock sync.Mutex //用来锁 + sessions map[string]*SessionStore //用来存储在内存 + list *list.List //用来做gc + } + + func (this *Provider) SessionInit(sid string) (session.Session, error) { + this.lock.Lock() + defer this.lock.Unlock() + v := make(map[interface{}]interface{}, 0) + newsess := &SessionStore{"sid": sid, "timeAccessed": time.Now(), "value": v} + this.sessions[sid] = newsess + this.list.Push(newsess) + return newsess + } + + func (this *Provider) SessionRead(sid string) (session.Session, error) { + if s, ok := this.sessions[sid]; ok { + return s, nil + } else { + sess, err := this.SessionInit(sid) + return sess, err + } + } + + func (this *Provider) SessionDestroy(sid string) bool { + if s, ok := this.sessions[sid]; ok { + delete(this.table, sid) + this.list.Remove(s) + return true + } else { + return false + } + } + + func (this *Provider) SessionGC(maxlifetime int64) { + this.lock.Lock() + defer this.lock.Unlock() + + for { + element := this.list.Back() + if element == nil { + break + } + if (element.Value.(*SessionStore).timeAccessed.Unix() + maxlifetime) < time.Now().Unix() { + this.list.Remove(element) + delete(this.table, element.Value.(*SessionStore).sid) + } else { + break + } + } + } + + func (this *Provider) SessionUpdate(sid string) bool { + this.lock.Lock() + defer this.lock.Unlock() + if element, ok := this.sessions[sid]; ok { + element.Value.(*SessionStore).value = s.value + this.moveToFront(element) + return true + } else { + return false + } + } + + func (this *Provider) moveToFront(element *list.Element) { + this.lock.Lock() + defer this.lock.Unlock() + element.Value.(*SessionStore).timeAccessed = time.Now() + this.list.MoveToFront(element) + } + + func init() { + session.Register("memory", d) + } + +上面这个代码实现了一个内存存储实现的session机制 ## links * [目录]() * 上一节: [Go如何使用session](<6.2.md>)