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  }