张金坤 8 سال پیش
والد
کامیت
7db2a3a1f5

+ 5 - 1
common/src/github.com/go-xweb/httpsession/manager.go

@@ -22,7 +22,7 @@ type Manager struct {
 }
 
 func Default() *Manager {
-	store := NewMemoryStore(DefaultMaxAge)
+	store := NewRedisStore(DefaultMaxAge)
 	key := string(GenRandKey(16))
 	return NewManager(store,
 		NewSha1Generator(key),
@@ -63,6 +63,10 @@ func (manager *Manager) Session(req *http.Request, rw http.ResponseWriter) *Sess
 		// is exist?
 		manager.afterCreated(session)
 		return session
+	} else {
+		cookie, _ := req.Cookie(manager.transfer.(*CookieTransfer).Name)
+		cookie.MaxAge = int(manager.transfer.(*CookieTransfer).MaxAge / time.Second)
+		http.SetCookie(rw, cookie)
 	}
 	return NewSession(id, manager.maxAge, manager)
 }

+ 124 - 0
common/src/github.com/go-xweb/httpsession/redissessionstore.go

@@ -0,0 +1,124 @@
+//session存放在redis中
+//多节点部署时,可以session不受内存存放的影响
+package httpsession
+
+import (
+	"encoding/json"
+	"qfw/util/redis"
+	"sync"
+	"time"
+)
+
+type redisStore struct {
+	lock       sync.RWMutex
+	last       time.Time
+	maxAge     time.Duration
+	GcInterval time.Duration
+}
+
+func NewRedisStore(maxAge time.Duration) *redisStore {
+	return &redisStore{
+		maxAge: maxAge, GcInterval: 10 * time.Second}
+}
+
+//设置超时
+func (store *redisStore) SetMaxAge(maxAge time.Duration) {
+	store.lock.Lock()
+	store.maxAge = maxAge
+	store.lock.Unlock()
+}
+
+//取数据,使用redis的超时,来控制session超时
+func (store *redisStore) Get(id Id, key string) interface{} {
+	store.lock.RLock()
+	bs, err := redis.GetBytes("session", string(id))
+	if err != nil {
+		store.lock.RUnlock()
+		return nil
+	}
+	redis.SetExpire("session", string(id), int(store.maxAge.Seconds()))
+	var userdata map[string]interface{}
+	json.Unmarshal(*bs, &userdata)
+	if v, ok := userdata[key]; ok {
+		store.lock.RUnlock()
+		store.last = time.Now()
+		return v
+	} else {
+		store.lock.RUnlock()
+		return nil
+	}
+}
+
+//设置数据
+func (store *redisStore) Set(id Id, key string, value interface{}) {
+	store.lock.RLock()
+	var userdata map[string]interface{}
+	bs, err := redis.GetBytes("session", string(id))
+	if err != nil {
+		userdata = make(map[string]interface{})
+	} else {
+		json.Unmarshal(*bs, &userdata)
+	}
+	userdata[key] = value
+	putdata, _ := json.Marshal(userdata)
+	redis.PutBytes("session", string(id), &putdata, int(store.maxAge.Seconds()))
+	store.lock.RUnlock()
+}
+
+func (store *redisStore) Add(id Id) {
+
+}
+
+func (store *redisStore) Del(id Id, key string) bool {
+	store.lock.RLock()
+	bs, err := redis.GetBytes("session", string(id))
+	if err != nil {
+		store.lock.RUnlock()
+		return true
+	}
+	var userdata map[string]interface{}
+	json.Unmarshal(*bs, &userdata)
+	delete(userdata, key)
+	putdata, _ := json.Marshal(userdata)
+	redis.PutBytes("session", string(id), &putdata, int(store.maxAge.Seconds()))
+	store.lock.RUnlock()
+	return true
+}
+
+//根据自定义字段,更新
+func (store *redisStore) UpdateByCustomField(findkey string, findvalue interface{}, setkey string, setvalue interface{}) bool {
+	store.lock.Lock()
+	bs, err := redis.GetBytes("session", findkey)
+	if err != nil {
+		store.lock.RUnlock()
+		return false
+	}
+	var data map[string]interface{}
+	json.Unmarshal(*bs, &data)
+
+	store.lock.Unlock()
+	return true
+}
+
+func (store *redisStore) Exist(id Id) bool {
+	store.lock.RLock()
+	defer store.lock.RUnlock()
+	ret, err := redis.Exists("session", string(id))
+	return err == nil && ret
+}
+
+func (store *redisStore) Clear(id Id) bool {
+	store.lock.Lock()
+	defer store.lock.Unlock()
+	redis.Del("session", string(id))
+	return true
+}
+
+func (store *redisStore) Run() error {
+	return nil
+}
+
+//TODO 加缓冲
+func (store *redisStore) GC() {
+	//log.Println("Gc")
+}