3.2 KiB
3.2 KiB
#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
- 下一节: 预防session劫持
LastModified
Id