|
@@ -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")
|
|
|
+}
|