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 }