#6.3 session存储 上一节我们介绍了Session管理器的实现原理,定义了存储session的接口,这小节我们将示例一个基于内存的session存储接口的实现,其他的存储方式,读者可以自行参考示例来实现,内存的实现请看下面的例子代码 package memory import ( "github.com/astaxie/session/" "time" "container/list" ) var d = &Provider{list:list.New()} 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机制。通过init函数注册到session管理器中。这样就可以方便的调用了。 ## links * [目录]() * 上一节: [Go如何使用session](<6.2.md>) * 下一节: [预防session劫持](<6.4.md>) ## LastModified * $Id$