Files
build-web-application-with-…/6.3.md
2012-09-25 00:01:32 +08:00

123 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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
* [目录](<preface.md>)
* 上一节: [Go如何使用session](<6.2.md>)
* 下一节: [预防session劫持](<6.4.md>)
## LastModified
* $Id$