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

125 lines
3.2 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 (
"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
* [目录](<preface.md>)
* 上一节: [Go如何使用session](<6.2.md>)
* 下一节: [预防session劫持](<6.4.md>)
## LastModified
* $Id$