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

3.2 KiB
Raw Blame History

#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管理器中。这样就可以方便的调用了。

LastModified

  • Id