mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
add package gkvdb; add kvdb storage feature for ghttp.Server
This commit is contained in:
@ -17,6 +17,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/database/gkvdb"
|
||||
|
||||
"github.com/gogf/gf/container/garray"
|
||||
"github.com/gogf/gf/container/gmap"
|
||||
"github.com/gogf/gf/container/gtype"
|
||||
@ -45,7 +47,8 @@ type (
|
||||
serveCache *gcache.Cache // 服务注册路由内存缓存
|
||||
routesMap map[string][]registeredRouteItem // 已经注册的路由及对应的注册方法文件地址(用以路由重复注册判断)
|
||||
statusHandlerMap map[string]HandlerFunc // 不同状态码下的注册处理方法(例如404状态时的处理方法)
|
||||
sessions *gcache.Cache // Session内存缓存
|
||||
sessions *gcache.Cache // Session内存存储
|
||||
sessionStorage *gkvdb.DB // Session物理存储
|
||||
logger *glog.Logger // 日志管理对象
|
||||
}
|
||||
|
||||
@ -209,6 +212,7 @@ func GetServer(name ...interface{}) *Server {
|
||||
serveCache: gcache.New(),
|
||||
routesMap: make(map[string][]registeredRouteItem),
|
||||
sessions: gcache.New(),
|
||||
sessionStorage: gkvdb.New(gkvdb.DefaultOptions(defaultServerConfig.SessionStoragePath)),
|
||||
servedCount: gtype.NewInt(),
|
||||
logger: glog.New(),
|
||||
}
|
||||
|
||||
@ -38,73 +38,75 @@ type LogHandler func(r *Request, error ...interface{})
|
||||
|
||||
// HTTP Server 设置结构体,静态配置
|
||||
type ServerConfig struct {
|
||||
Addr string // 监听IP和端口,监听本地所有IP使用":端口"(支持多个地址,使用","号分隔)
|
||||
HTTPSAddr string // HTTPS服务监听地址(支持多个地址,使用","号分隔)
|
||||
HTTPSCertPath string // HTTPS证书文件路径
|
||||
HTTPSKeyPath string // HTTPS签名文件路径
|
||||
Handler http.Handler // 默认的处理函数
|
||||
ReadTimeout time.Duration // 读取超时
|
||||
WriteTimeout time.Duration // 写入超时
|
||||
IdleTimeout time.Duration // 等待超时
|
||||
MaxHeaderBytes int // 最大的header长度
|
||||
TLSConfig tls.Config // HTTPS证书配置
|
||||
KeepAlive bool // 是否开启长连接
|
||||
ServerAgent string // Server Agent
|
||||
View *gview.View // 模板引擎对象
|
||||
Rewrites map[string]string // URI Rewrite重写配置
|
||||
IndexFiles []string // Static: 默认访问的文件列表
|
||||
IndexFolder bool // Static: 如果访问目录是否显示目录列表
|
||||
ServerRoot string // Static: 服务器服务的本地目录根路径(检索优先级比StaticPaths低)
|
||||
SearchPaths []string // Static: 静态文件搜索目录(包含ServerRoot,按照优先级进行排序)
|
||||
StaticPaths []staticPathItem // Static: 静态文件目录映射(按照优先级进行排序)
|
||||
FileServerEnabled bool // Static: 是否允许静态文件服务(通过静态文件服务方法调用自动识别)
|
||||
CookieMaxAge int64 // Cookie: 有效期(秒)
|
||||
CookiePath string // Cookie: 有效Path(注意同时也会影响SessionID)
|
||||
CookieDomain string // Cookie: 有效Domain(注意同时也会影响SessionID)
|
||||
SessionMaxAge int64 // Session: 有效期(秒)
|
||||
SessionIdName string // Session: SessionId
|
||||
DenyIps []string // Security: 不允许访问的ip列表,支持ip前缀过滤,如: 10 将不允许10开头的ip访问
|
||||
AllowIps []string // Security: 仅允许访问的ip列表,支持ip前缀过滤,如: 10 将仅允许10开头的ip访问
|
||||
DenyRoutes []string // Security: 不允许访问的路由规则列表
|
||||
LogPath string // Logging: 存放日志的目录路径(默认为空,表示不写文件)
|
||||
LogHandler LogHandler // Logging: 日志配置: 自定义日志处理回调方法(默认为空)
|
||||
LogStdout bool // Logging: 是否打印日志到终端(默认开启)
|
||||
ErrorLogEnabled bool // Logging: 是否开启error log(默认开启)
|
||||
AccessLogEnabled bool // Logging: 是否开启access log(默认关闭)
|
||||
NameToUriType int // Mess: 服务注册时对象和方法名称转换为URI时的规则
|
||||
GzipContentTypes []string // Mess: 允许进行gzip压缩的文件类型
|
||||
DumpRouteMap bool // Mess: 是否在程序启动时默认打印路由表信息
|
||||
RouterCacheExpire int // Mess: 路由检索缓存过期时间(秒)
|
||||
Addr string // 监听IP和端口,监听本地所有IP使用":端口"(支持多个地址,使用","号分隔)
|
||||
HTTPSAddr string // HTTPS服务监听地址(支持多个地址,使用","号分隔)
|
||||
HTTPSCertPath string // HTTPS证书文件路径
|
||||
HTTPSKeyPath string // HTTPS签名文件路径
|
||||
Handler http.Handler // 默认的处理函数
|
||||
ReadTimeout time.Duration // 读取超时
|
||||
WriteTimeout time.Duration // 写入超时
|
||||
IdleTimeout time.Duration // 等待超时
|
||||
MaxHeaderBytes int // 最大的header长度
|
||||
TLSConfig tls.Config // HTTPS证书配置
|
||||
KeepAlive bool // 是否开启长连接
|
||||
ServerAgent string // Server Agent
|
||||
View *gview.View // 模板引擎对象
|
||||
Rewrites map[string]string // URI Rewrite重写配置
|
||||
IndexFiles []string // Static: 默认访问的文件列表
|
||||
IndexFolder bool // Static: 如果访问目录是否显示目录列表
|
||||
ServerRoot string // Static: 服务器服务的本地目录根路径(检索优先级比StaticPaths低)
|
||||
SearchPaths []string // Static: 静态文件搜索目录(包含ServerRoot,按照优先级进行排序)
|
||||
StaticPaths []staticPathItem // Static: 静态文件目录映射(按照优先级进行排序)
|
||||
FileServerEnabled bool // Static: 是否允许静态文件服务(通过静态文件服务方法调用自动识别)
|
||||
CookieMaxAge int64 // Cookie: 有效期(秒)
|
||||
CookiePath string // Cookie: 有效Path(注意同时也会影响SessionID)
|
||||
CookieDomain string // Cookie: 有效Domain(注意同时也会影响SessionID)
|
||||
SessionMaxAge int64 // Session: 有效期(秒)
|
||||
SessionIdName string // Session: SessionId
|
||||
SessionStoragePath string // Session: 存储路径
|
||||
DenyIps []string // Security: 不允许访问的ip列表,支持ip前缀过滤,如: 10 将不允许10开头的ip访问
|
||||
AllowIps []string // Security: 仅允许访问的ip列表,支持ip前缀过滤,如: 10 将仅允许10开头的ip访问
|
||||
DenyRoutes []string // Security: 不允许访问的路由规则列表
|
||||
LogPath string // Logging: 存放日志的目录路径(默认为空,表示不写文件)
|
||||
LogHandler LogHandler // Logging: 日志配置: 自定义日志处理回调方法(默认为空)
|
||||
LogStdout bool // Logging: 是否打印日志到终端(默认开启)
|
||||
ErrorLogEnabled bool // Logging: 是否开启error log(默认开启)
|
||||
AccessLogEnabled bool // Logging: 是否开启access log(默认关闭)
|
||||
NameToUriType int // Mess: 服务注册时对象和方法名称转换为URI时的规则
|
||||
GzipContentTypes []string // Mess: 允许进行gzip压缩的文件类型
|
||||
DumpRouteMap bool // Mess: 是否在程序启动时默认打印路由表信息
|
||||
RouterCacheExpire int // Mess: 路由检索缓存过期时间(秒)
|
||||
}
|
||||
|
||||
// 默认HTTP Server配置
|
||||
var defaultServerConfig = ServerConfig{
|
||||
Addr: "",
|
||||
HTTPSAddr: "",
|
||||
Handler: nil,
|
||||
ReadTimeout: 60 * time.Second,
|
||||
WriteTimeout: 60 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
MaxHeaderBytes: 1024,
|
||||
KeepAlive: true,
|
||||
View: gview.Instance(),
|
||||
IndexFiles: []string{"index.html", "index.htm"},
|
||||
IndexFolder: false,
|
||||
ServerAgent: "gf http server",
|
||||
ServerRoot: "",
|
||||
StaticPaths: make([]staticPathItem, 0),
|
||||
FileServerEnabled: false,
|
||||
CookieMaxAge: gDEFAULT_COOKIE_MAX_AGE,
|
||||
CookiePath: gDEFAULT_COOKIE_PATH,
|
||||
CookieDomain: "",
|
||||
SessionMaxAge: gDEFAULT_SESSION_MAX_AGE,
|
||||
SessionIdName: gDEFAULT_SESSION_ID_NAME,
|
||||
LogStdout: true,
|
||||
ErrorLogEnabled: true,
|
||||
AccessLogEnabled: false,
|
||||
DumpRouteMap: true,
|
||||
RouterCacheExpire: 60,
|
||||
Rewrites: make(map[string]string),
|
||||
Addr: "",
|
||||
HTTPSAddr: "",
|
||||
Handler: nil,
|
||||
ReadTimeout: 60 * time.Second,
|
||||
WriteTimeout: 60 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
MaxHeaderBytes: 1024,
|
||||
KeepAlive: true,
|
||||
View: gview.Instance(),
|
||||
IndexFiles: []string{"index.html", "index.htm"},
|
||||
IndexFolder: false,
|
||||
ServerAgent: "gf http server",
|
||||
ServerRoot: "",
|
||||
StaticPaths: make([]staticPathItem, 0),
|
||||
FileServerEnabled: false,
|
||||
CookieMaxAge: gDEFAULT_COOKIE_MAX_AGE,
|
||||
CookiePath: gDEFAULT_COOKIE_PATH,
|
||||
CookieDomain: "",
|
||||
SessionMaxAge: gDEFAULT_SESSION_MAX_AGE,
|
||||
SessionIdName: gDEFAULT_SESSION_ID_NAME,
|
||||
SessionStoragePath: gfile.TempDir() + gfile.Separator + "gfsessions",
|
||||
LogStdout: true,
|
||||
ErrorLogEnabled: true,
|
||||
AccessLogEnabled: false,
|
||||
DumpRouteMap: true,
|
||||
RouterCacheExpire: 60,
|
||||
Rewrites: make(map[string]string),
|
||||
}
|
||||
|
||||
// 获取默认的http server设置
|
||||
|
||||
@ -6,7 +6,12 @@
|
||||
|
||||
package ghttp
|
||||
|
||||
import "github.com/gogf/gf/os/glog"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/os/gfile"
|
||||
"github.com/gogf/gf/os/glog"
|
||||
)
|
||||
|
||||
// 设置http server参数 - SessionMaxAge
|
||||
func (s *Server) SetSessionMaxAge(age int64) {
|
||||
@ -26,6 +31,22 @@ func (s *Server) SetSessionIdName(name string) {
|
||||
s.config.SessionIdName = name
|
||||
}
|
||||
|
||||
// 设置http server参数 - SessionStoragePath
|
||||
func (s *Server) SetSessionStoragePath(path string) {
|
||||
if s.Status() == SERVER_STATUS_RUNNING {
|
||||
glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
|
||||
return
|
||||
}
|
||||
realPath, _ := gfile.Search(path)
|
||||
if realPath != "" {
|
||||
glog.Fatal(fmt.Sprintf(`[ghttp] SetSessionStoragePath failed: '%s' does not exist`, path))
|
||||
}
|
||||
s.config.SessionStoragePath = realPath
|
||||
if err := s.sessionStorage.SetPath(realPath); err != nil {
|
||||
glog.Fatal(fmt.Sprintf(`[ghttp] SetSessionStoragePath failed: %s`, err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
// 获取http server参数 - SessionMaxAge
|
||||
func (s *Server) GetSessionMaxAge() int64 {
|
||||
return s.config.SessionMaxAge
|
||||
@ -35,3 +56,8 @@ func (s *Server) GetSessionMaxAge() int64 {
|
||||
func (s *Server) GetSessionIdName() string {
|
||||
return s.config.SessionIdName
|
||||
}
|
||||
|
||||
// 获取http server参数 - SessionStoragePath
|
||||
func (s *Server) GetSessionStoragePath() string {
|
||||
return s.config.SessionStoragePath
|
||||
}
|
||||
|
||||
@ -57,9 +57,19 @@ func (s *Session) init() {
|
||||
s.server = s.request.Server
|
||||
if id := s.request.GetSessionId(); id != "" {
|
||||
if v := s.server.sessions.Get(id); v != nil {
|
||||
// 纯内存查询
|
||||
s.id = id
|
||||
s.data = v.(*gmap.StrAnyMap)
|
||||
return
|
||||
} else {
|
||||
// 持久化恢复
|
||||
data := s.server.sessionStorage.Get([]byte(id))
|
||||
if data != nil {
|
||||
s.id = id
|
||||
s.data = gmap.NewStrAnyMap(true)
|
||||
s.Restore(data)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
// 否则执行初始化创建
|
||||
@ -165,6 +175,16 @@ func (s *Session) Clear() {
|
||||
// 更新过期时间(如果用在守护进程中长期使用,需要手动调用进行更新,防止超时被清除)
|
||||
func (s *Session) UpdateExpire() {
|
||||
if len(s.id) > 0 && s.data.Size() > 0 {
|
||||
// 优先持久化存储
|
||||
if s.dirty {
|
||||
data, _ := s.Export()
|
||||
s.server.sessionStorage.Set(
|
||||
[]byte(s.id),
|
||||
data,
|
||||
time.Duration(s.server.GetSessionMaxAge())*time.Second,
|
||||
)
|
||||
}
|
||||
// 其次更新内存TTL
|
||||
s.server.sessions.Set(s.id, s.data, s.server.GetSessionMaxAge()*1000)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user