110 lines
2.0 KiB
Go
110 lines
2.0 KiB
Go
package session
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"github.com/garyburd/redigo/redis"
|
|
"sync"
|
|
)
|
|
|
|
type RedisSession struct {
|
|
sessionId string
|
|
pool *redis.Pool
|
|
//设置session key value
|
|
sessionMap map[string]interface{}
|
|
rwLock sync.RWMutex
|
|
flag int
|
|
}
|
|
|
|
//用常量定义状态
|
|
|
|
const (
|
|
//内存数据没变化
|
|
SessionFlagNone = iota
|
|
|
|
SessionFlagModify
|
|
)
|
|
|
|
//构造函数
|
|
|
|
func NewRedisSession(pool *redis.Pool, id string) *RedisSession {
|
|
s := &RedisSession{
|
|
sessionId: id,
|
|
pool: pool,
|
|
sessionMap: make(map[string]interface{}, 16),
|
|
flag: SessionFlagNone,
|
|
}
|
|
return s
|
|
}
|
|
|
|
func (r *RedisSession) Set(key string, value interface{}) (err error) {
|
|
r.rwLock.Lock()
|
|
defer r.rwLock.Unlock()
|
|
r.sessionMap[key] = value
|
|
//flag
|
|
r.flag = SessionFlagModify
|
|
return
|
|
}
|
|
|
|
func (r *RedisSession) Save() (err error) {
|
|
r.rwLock.RLock()
|
|
defer r.rwLock.RUnlock()
|
|
//如果数据没变,不需要存
|
|
if r.flag != SessionFlagModify {
|
|
return
|
|
}
|
|
//内存中的sessionMap进行序列化
|
|
data, err := json.Marshal(r.sessionMap)
|
|
if err != nil {
|
|
return
|
|
}
|
|
//获取redis链接
|
|
_, err = r.pool.Get().Do("SET", r.sessionId, string(data))
|
|
r.flag = SessionFlagNone
|
|
if err != nil {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
func (r *RedisSession) Get(key string) (result interface{}, err error) {
|
|
r.rwLock.RLock()
|
|
defer r.rwLock.RUnlock()
|
|
|
|
//判断内存有没有数据
|
|
result, ok := r.sessionMap[key]
|
|
if !ok {
|
|
err = errors.New("key not found")
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
//从redis里再次加载
|
|
|
|
func (r *RedisSession) LoadFormRedis() (err error) {
|
|
reply, err := r.pool.Get().Do("GET", r.sessionId)
|
|
if err != nil {
|
|
return
|
|
}
|
|
//转字符串
|
|
data, err := redis.String(reply, err)
|
|
if err != nil {
|
|
return
|
|
}
|
|
//取到的东西反序列化到内存的map中
|
|
err = json.Unmarshal([]byte(data), &r.sessionMap)
|
|
if err != nil {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
func (r *RedisSession) Del(key string) (err error) {
|
|
r.rwLock.Lock()
|
|
defer r.rwLock.Unlock()
|
|
r.flag = SessionFlagModify
|
|
delete(r.sessionMap, key)
|
|
return
|
|
}
|