mirror of
https://gitee.com/johng/gf
synced 2026-07-06 13:42:46 +08:00
improve ghttp for session
This commit is contained in:
@ -9,11 +9,12 @@ package ghttp
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/os/glog"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/os/glog"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -25,7 +26,7 @@ const (
|
||||
NAME_TO_URI_TYPE_CAMEL = 3 // 采用驼峰命名方式
|
||||
gDEFAULT_COOKIE_PATH = "/" // 默认path
|
||||
gDEFAULT_COOKIE_MAX_AGE = 86400 * 365 // 默认cookie有效期(一年)
|
||||
gDEFAULT_SESSION_MAX_AGE = 600000 // 默认session有效期(600秒)
|
||||
gDEFAULT_SESSION_MAX_AGE = 86400 // 默认session有效期(一天)
|
||||
gDEFAULT_SESSION_ID_NAME = "gfsessionid" // 默认存放Cookie中的SessionId名称
|
||||
gCHANGE_CONFIG_WHILE_RUNNING_ERROR = "cannot be changed while running"
|
||||
)
|
||||
|
||||
@ -8,14 +8,16 @@
|
||||
package ghttp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/g/container/gmap"
|
||||
"github.com/gogf/gf/g/container/gvar"
|
||||
"github.com/gogf/gf/g/os/gtime"
|
||||
"github.com/gogf/gf/g/util/gconv"
|
||||
"github.com/gogf/gf/g/util/grand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SESSION对象
|
||||
@ -62,13 +64,18 @@ func (s *Session) init() {
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
|
||||
func (s *Session) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(s.data)
|
||||
}
|
||||
|
||||
// 获取/创建SessionId
|
||||
func (s *Session) Id() string {
|
||||
s.init()
|
||||
return s.id
|
||||
}
|
||||
|
||||
// 获取当前session所有数据
|
||||
// 获取当前session所有数据,注意是值拷贝
|
||||
func (s *Session) Map() map[string]interface{} {
|
||||
if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" {
|
||||
s.init()
|
||||
@ -77,6 +84,15 @@ func (s *Session) Map() map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获得session map大小
|
||||
func (s *Session) Size() int {
|
||||
if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" {
|
||||
s.init()
|
||||
return s.data.Size()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// 设置session
|
||||
func (s *Session) Set(key string, value interface{}) {
|
||||
s.init()
|
||||
@ -117,7 +133,7 @@ func (s *Session) GetVar(key string, def ...interface{}) *gvar.Var {
|
||||
return gvar.New(s.Get(key, def...), true)
|
||||
}
|
||||
|
||||
// 删除session
|
||||
// 删除指定session键值对
|
||||
func (s *Session) Remove(key string) {
|
||||
if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" {
|
||||
s.init()
|
||||
@ -125,6 +141,17 @@ func (s *Session) Remove(key string) {
|
||||
}
|
||||
}
|
||||
|
||||
// 从json字符串中恢复session数据
|
||||
func (s *Session) RestoreFromJson(data []byte) (err error) {
|
||||
if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" {
|
||||
s.init()
|
||||
s.data.LockFunc(func(m map[string]interface{}) {
|
||||
err = json.Unmarshal(data, &m)
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 清空session
|
||||
func (s *Session) Clear() {
|
||||
if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" {
|
||||
@ -228,7 +255,34 @@ func (s *Session) GetDuration(key string, def ...interface{}) time.Duration {
|
||||
return gconv.Duration(s.Get(key, def...))
|
||||
}
|
||||
|
||||
// 将变量转换为对象,注意 pointer 参数必须为struct指针
|
||||
func (s *Session) GetMap(value interface{}, tags ...string) map[string]interface{} {
|
||||
return gconv.Map(value, tags...)
|
||||
}
|
||||
|
||||
func (s *Session) GetMapDeep(value interface{}, tags ...string) map[string]interface{} {
|
||||
return gconv.MapDeep(value, tags...)
|
||||
}
|
||||
|
||||
func (s *Session) GetMaps(value interface{}, tags ...string) []map[string]interface{} {
|
||||
return gconv.Maps(value, tags...)
|
||||
}
|
||||
|
||||
func (s *Session) GetMapsDeep(value interface{}, tags ...string) []map[string]interface{} {
|
||||
return gconv.MapsDeep(value, tags...)
|
||||
}
|
||||
|
||||
func (s *Session) GetStruct(key string, pointer interface{}, mapping ...map[string]string) error {
|
||||
return gconv.Struct(s.Get(key), pointer, mapping...)
|
||||
}
|
||||
|
||||
func (s *Session) GetStructDeep(key string, pointer interface{}, mapping ...map[string]string) error {
|
||||
return gconv.StructDeep(s.Get(key), pointer, mapping...)
|
||||
}
|
||||
|
||||
func (s *Session) GetStructs(key string, pointer interface{}, mapping ...map[string]string) error {
|
||||
return gconv.Structs(s.Get(key), pointer, mapping...)
|
||||
}
|
||||
|
||||
func (s *Session) GetStructsDeep(key string, pointer interface{}, mapping ...map[string]string) error {
|
||||
return gconv.StructsDeep(s.Get(key), pointer, mapping...)
|
||||
}
|
||||
|
||||
@ -379,40 +379,40 @@ func Interfaces(i interface{}) []interface{} {
|
||||
}
|
||||
|
||||
// Maps converts <i> to []map[string]interface{}.
|
||||
func Maps(i interface{}) []map[string]interface{} {
|
||||
if i == nil {
|
||||
func Maps(value interface{}, tags ...string) []map[string]interface{} {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
if r, ok := i.([]map[string]interface{}); ok {
|
||||
if r, ok := value.([]map[string]interface{}); ok {
|
||||
return r
|
||||
} else {
|
||||
array := Interfaces(i)
|
||||
array := Interfaces(value)
|
||||
if len(array) == 0 {
|
||||
return nil
|
||||
}
|
||||
list := make([]map[string]interface{}, len(array))
|
||||
for k, v := range array {
|
||||
list[k] = Map(v)
|
||||
list[k] = Map(v, tags...)
|
||||
}
|
||||
return list
|
||||
}
|
||||
}
|
||||
|
||||
// MapsDeep converts <i> to []map[string]interface{} recursively.
|
||||
func MapsDeep(i interface{}) []map[string]interface{} {
|
||||
if i == nil {
|
||||
func MapsDeep(value interface{}, tags ...string) []map[string]interface{} {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
if r, ok := i.([]map[string]interface{}); ok {
|
||||
if r, ok := value.([]map[string]interface{}); ok {
|
||||
return r
|
||||
} else {
|
||||
array := Interfaces(i)
|
||||
array := Interfaces(value)
|
||||
if len(array) == 0 {
|
||||
return nil
|
||||
}
|
||||
list := make([]map[string]interface{}, len(array))
|
||||
for k, v := range array {
|
||||
list[k] = MapDeep(v)
|
||||
list[k] = MapDeep(v, tags...)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
2
geg/net/ghttp/server/session/config.toml
Normal file
2
geg/net/ghttp/server/session/config.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[redis]
|
||||
default = "127.0.0.1:6379,10"
|
||||
@ -22,7 +22,7 @@ func (c *Controller) DoLogin() {
|
||||
}
|
||||
|
||||
func (c *Controller) Main() {
|
||||
c.Response.WriteJson(c.Session.Data())
|
||||
c.Response.WriteJson(c.Session.Map())
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
78
geg/net/ghttp/server/session/session_redis.go
Normal file
78
geg/net/ghttp/server/session/session_redis.go
Normal file
@ -0,0 +1,78 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/gogf/gf/g"
|
||||
"github.com/gogf/gf/g/net/ghttp"
|
||||
"github.com/gogf/gf/g/os/gtime"
|
||||
)
|
||||
|
||||
// 测试,SESSION写入
|
||||
func SessionSet(r *ghttp.Request) {
|
||||
r.Session.Set("time", gtime.Second())
|
||||
r.Response.WriteJson("ok")
|
||||
}
|
||||
|
||||
// 测试,SESSION读取
|
||||
func SessionGet(r *ghttp.Request) {
|
||||
r.Response.WriteJson(r.Session.Map())
|
||||
}
|
||||
|
||||
// 请求处理之前将Redis中的数据读取出来并存储到SESSION对象中。
|
||||
func RedisHandlerGet(r *ghttp.Request) {
|
||||
if !r.IsFileRequest() {
|
||||
sessionId := r.Cookie.GetSessionId()
|
||||
if sessionId == "" {
|
||||
return
|
||||
}
|
||||
value, err := g.Redis().DoVar("GET", sessionId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !value.IsNil() {
|
||||
err := r.Session.RestoreFromJson(value.Bytes())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 请求结束时将SESSION数据存储到Redis中,或者在SESSION删除时也删除Redis中的数据。
|
||||
func RedisHandlerSet(r *ghttp.Request) {
|
||||
if !r.IsFileRequest() {
|
||||
sessionId := r.Cookie.GetSessionId()
|
||||
if sessionId == "" {
|
||||
return
|
||||
}
|
||||
err := (error)(nil)
|
||||
if r.Session.Size() > 0 {
|
||||
value, err := json.Marshal(r.Session)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = g.Redis().Do("SETEX", r.Cookie.GetSessionId(), r.Server.GetSessionMaxAge(), value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
_, err = g.Redis().Do("DEL", r.Cookie.GetSessionId())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
s := g.Server()
|
||||
s.BindHandler("/set", SessionSet)
|
||||
s.BindHandler("/get", SessionGet)
|
||||
s.BindHookHandlerByMap("/*", map[string]ghttp.HandlerFunc{
|
||||
ghttp.HOOK_BEFORE_SERVE: RedisHandlerGet,
|
||||
ghttp.HOOK_AFTER_SERVE: RedisHandlerSet,
|
||||
})
|
||||
s.SetPort(8199)
|
||||
s.Run()
|
||||
}
|
||||
Reference in New Issue
Block a user