github.com/zhongdalu/gf@v1.0.0/g/net/ghttp/ghttp_server_session.go (about) 1 // Copyright 2017-2019 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 7 package ghttp 8 9 import ( 10 "encoding/json" 11 "strconv" 12 "strings" 13 "time" 14 15 "github.com/zhongdalu/gf/g/container/gmap" 16 "github.com/zhongdalu/gf/g/container/gvar" 17 "github.com/zhongdalu/gf/g/os/gtime" 18 "github.com/zhongdalu/gf/g/util/gconv" 19 "github.com/zhongdalu/gf/g/util/grand" 20 ) 21 22 // SESSION对象,并发安全 23 type Session struct { 24 id string // SessionId 25 data *gmap.StrAnyMap // Session数据 26 dirty bool // 数据是否被修改 27 server *Server // 所属Server 28 request *Request // 关联的请求 29 } 30 31 // 生成一个唯一的SessionId字符串,长度18位。 32 func makeSessionId() string { 33 return strings.ToUpper(strconv.FormatInt(gtime.Nanosecond(), 36) + grand.Str(6)) 34 } 35 36 // 获取或者生成一个session对象(延迟初始化) 37 func GetSession(r *Request) *Session { 38 if r.Session != nil { 39 return r.Session 40 } 41 return &Session{ 42 request: r, 43 } 44 } 45 46 // 延迟初始化 47 func (s *Session) init() { 48 if len(s.id) == 0 { 49 s.server = s.request.Server 50 if id := s.request.Cookie.GetSessionId(); id != "" { 51 if data := s.server.sessions.Get(id); data != nil { 52 s.id = id 53 s.data = data.(*gmap.StrAnyMap) 54 return 55 } 56 } 57 // 否则执行初始化创建 58 s.id = s.request.Cookie.MakeSessionId() 59 s.data = gmap.NewStrAnyMap() 60 s.server.sessions.Set(s.id, s.data, s.server.GetSessionMaxAge()*1000) 61 s.dirty = true 62 } 63 } 64 65 // 获取/创建SessionId 66 func (s *Session) Id() string { 67 s.init() 68 return s.id 69 } 70 71 // 获取当前session所有数据,注意是值拷贝 72 func (s *Session) Map() map[string]interface{} { 73 if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" { 74 s.init() 75 return s.data.Map() 76 } 77 return nil 78 } 79 80 // 获得session map大小 81 func (s *Session) Size() int { 82 if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" { 83 s.init() 84 return s.data.Size() 85 } 86 return 0 87 } 88 89 // 设置session 90 func (s *Session) Set(key string, value interface{}) { 91 s.init() 92 s.data.Set(key, value) 93 s.dirty = true 94 } 95 96 // 批量设置 97 func (s *Session) Sets(m map[string]interface{}) { 98 s.init() 99 s.data.Sets(m) 100 s.dirty = true 101 } 102 103 // 判断键名是否存在 104 func (s *Session) Contains(key string) bool { 105 if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" { 106 s.init() 107 return s.data.Contains(key) 108 } 109 return false 110 } 111 112 // 判断session是否有修改(包括新创建) 113 func (s *Session) IsDirty() bool { 114 return s.dirty 115 } 116 117 // 删除指定session键值对 118 func (s *Session) Remove(key string) { 119 if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" { 120 s.init() 121 s.data.Remove(key) 122 s.dirty = true 123 } 124 } 125 126 // 将session数据导出为[]byte数据(目前使用json进行序列化) 127 func (s *Session) Export() (data []byte, err error) { 128 if s.Size() > 0 { 129 data, err = json.Marshal(s.data) 130 } 131 return 132 } 133 134 // 从[]byte中恢复session数据(目前使用json进行序列化) 135 func (s *Session) Restore(data []byte) (err error) { 136 if len(data) == 0 { 137 return nil 138 } 139 if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" { 140 s.init() 141 s.data.LockFunc(func(m map[string]interface{}) { 142 err = json.Unmarshal(data, &m) 143 }) 144 } 145 return 146 } 147 148 // 清空session 149 func (s *Session) Clear() { 150 if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" { 151 s.init() 152 s.data.Clear() 153 s.dirty = true 154 } 155 } 156 157 // 更新过期时间(如果用在守护进程中长期使用,需要手动调用进行更新,防止超时被清除) 158 func (s *Session) UpdateExpire() { 159 if len(s.id) > 0 && s.data.Size() > 0 { 160 s.server.sessions.Set(s.id, s.data, s.server.GetSessionMaxAge()*1000) 161 } 162 } 163 164 // 获取SESSION变量 165 func (s *Session) Get(key string, def ...interface{}) interface{} { 166 if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" { 167 s.init() 168 if v := s.data.Get(key); v != nil { 169 return v 170 } 171 } 172 if len(def) > 0 { 173 return def[0] 174 } 175 return nil 176 } 177 178 // 获取SESSION,建议都用该方法获取参数 179 func (s *Session) GetVar(key string, def ...interface{}) *gvar.Var { 180 return gvar.New(s.Get(key, def...), true) 181 } 182 183 func (s *Session) GetString(key string, def ...interface{}) string { 184 return gconv.String(s.Get(key, def...)) 185 } 186 187 func (s *Session) GetBool(key string, def ...interface{}) bool { 188 return gconv.Bool(s.Get(key, def...)) 189 } 190 191 func (s *Session) GetInt(key string, def ...interface{}) int { 192 return gconv.Int(s.Get(key, def...)) 193 } 194 195 func (s *Session) GetInt8(key string, def ...interface{}) int8 { 196 return gconv.Int8(s.Get(key, def...)) 197 } 198 199 func (s *Session) GetInt16(key string, def ...interface{}) int16 { 200 return gconv.Int16(s.Get(key, def...)) 201 } 202 203 func (s *Session) GetInt32(key string, def ...interface{}) int32 { 204 return gconv.Int32(s.Get(key, def...)) 205 } 206 207 func (s *Session) GetInt64(key string, def ...interface{}) int64 { 208 return gconv.Int64(s.Get(key, def...)) 209 } 210 211 func (s *Session) GetUint(key string, def ...interface{}) uint { 212 return gconv.Uint(s.Get(key, def...)) 213 } 214 215 func (s *Session) GetUint8(key string, def ...interface{}) uint8 { 216 return gconv.Uint8(s.Get(key, def...)) 217 } 218 219 func (s *Session) GetUint16(key string, def ...interface{}) uint16 { 220 return gconv.Uint16(s.Get(key, def...)) 221 } 222 223 func (s *Session) GetUint32(key string, def ...interface{}) uint32 { 224 return gconv.Uint32(s.Get(key, def...)) 225 } 226 227 func (s *Session) GetUint64(key string, def ...interface{}) uint64 { 228 return gconv.Uint64(s.Get(key, def...)) 229 } 230 231 func (s *Session) GetFloat32(key string, def ...interface{}) float32 { 232 return gconv.Float32(s.Get(key, def...)) 233 } 234 235 func (s *Session) GetFloat64(key string, def ...interface{}) float64 { 236 return gconv.Float64(s.Get(key, def...)) 237 } 238 239 func (s *Session) GetBytes(key string, def ...interface{}) []byte { 240 return gconv.Bytes(s.Get(key, def...)) 241 } 242 243 func (s *Session) GetInts(key string, def ...interface{}) []int { 244 return gconv.Ints(s.Get(key, def...)) 245 } 246 247 func (s *Session) GetFloats(key string, def ...interface{}) []float64 { 248 return gconv.Floats(s.Get(key, def...)) 249 } 250 251 func (s *Session) GetStrings(key string, def ...interface{}) []string { 252 return gconv.Strings(s.Get(key, def...)) 253 } 254 255 func (s *Session) GetInterfaces(key string, def ...interface{}) []interface{} { 256 return gconv.Interfaces(s.Get(key, def...)) 257 } 258 259 func (s *Session) GetTime(key string, format ...string) time.Time { 260 return gconv.Time(s.Get(key), format...) 261 } 262 263 func (s *Session) GetGTime(key string, format ...string) *gtime.Time { 264 return gconv.GTime(s.Get(key), format...) 265 } 266 267 func (s *Session) GetDuration(key string, def ...interface{}) time.Duration { 268 return gconv.Duration(s.Get(key, def...)) 269 } 270 271 func (s *Session) GetMap(value interface{}, tags ...string) map[string]interface{} { 272 return gconv.Map(value, tags...) 273 } 274 275 func (s *Session) GetMapDeep(value interface{}, tags ...string) map[string]interface{} { 276 return gconv.MapDeep(value, tags...) 277 } 278 279 func (s *Session) GetMaps(value interface{}, tags ...string) []map[string]interface{} { 280 return gconv.Maps(value, tags...) 281 } 282 283 func (s *Session) GetMapsDeep(value interface{}, tags ...string) []map[string]interface{} { 284 return gconv.MapsDeep(value, tags...) 285 } 286 287 func (s *Session) GetStruct(key string, pointer interface{}, mapping ...map[string]string) error { 288 return gconv.Struct(s.Get(key), pointer, mapping...) 289 } 290 291 func (s *Session) GetStructDeep(key string, pointer interface{}, mapping ...map[string]string) error { 292 return gconv.StructDeep(s.Get(key), pointer, mapping...) 293 } 294 295 func (s *Session) GetStructs(key string, pointer interface{}, mapping ...map[string]string) error { 296 return gconv.Structs(s.Get(key), pointer, mapping...) 297 } 298 299 func (s *Session) GetStructsDeep(key string, pointer interface{}, mapping ...map[string]string) error { 300 return gconv.StructsDeep(s.Get(key), pointer, mapping...) 301 }