update session.save

add  response.makeAsync, default use sync mode and not need response.end()
This commit is contained in:
Star 2026-03-23 00:12:29 +08:00
parent ee7007f050
commit 951a9a7397
5 changed files with 57 additions and 25 deletions

37
go.mod
View File

@ -1,36 +1,37 @@
module apigo.cc/gojs/service
go 1.24.0
go 1.25.0
require (
apigo.cc/gojs v0.0.32
apigo.cc/gojs v0.0.34
apigo.cc/gojs/console v0.0.4
apigo.cc/gojs/file v0.0.7
apigo.cc/gojs/http v0.0.8
apigo.cc/gojs/runtime v0.0.4
apigo.cc/gojs/file v0.0.8
apigo.cc/gojs/http v0.0.10
apigo.cc/gojs/runtime v0.0.5
apigo.cc/gojs/task v0.0.8
apigo.cc/gojs/util v0.0.16
apigo.cc/gojs/util v0.0.18
github.com/gorilla/websocket v1.5.3
github.com/ssgo/config v1.7.10
github.com/ssgo/discover v1.7.10
github.com/ssgo/httpclient v1.7.8
github.com/ssgo/log v1.7.10
github.com/ssgo/httpclient v1.7.9
github.com/ssgo/log v1.7.11
github.com/ssgo/redis v1.7.8
github.com/ssgo/s v1.7.25
github.com/ssgo/standard v1.7.7
github.com/ssgo/u v1.7.23
github.com/ssgo/s v1.7.26
github.com/ssgo/standard v1.7.8
github.com/ssgo/u v1.7.24
)
require (
github.com/ZZMarquis/gm v1.3.2 // indirect
github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/emmansun/gmsm v0.40.0 // indirect
github.com/emmansun/gmsm v0.41.1 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-rod/rod v0.116.2 // indirect
github.com/go-rod/stealth v0.4.9 // indirect
github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect
github.com/gomodule/redigo v1.9.2 // indirect
github.com/google/pprof v0.0.0-20250903194437-c28834ac2320 // indirect
github.com/gomodule/redigo v1.9.3 // indirect
github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc // indirect
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
github.com/obscuren/ecies v0.0.0-20150213224233-7c0f4a9b18d9 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
@ -46,9 +47,9 @@ require (
github.com/ysmood/gson v0.7.3 // indirect
github.com/ysmood/leakless v0.9.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // indirect
golang.org/x/crypto v0.49.0 // indirect
golang.org/x/net v0.52.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/text v0.35.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

View File

@ -17,6 +17,11 @@ type Response struct {
Id string
}
func (r *Response) MakeAsync(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
r.endCh = make(chan bool, 1)
return nil
}
func (r *Response) End(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(argsIn.Arguments) > 0 {
r.result = argsIn.Arguments[0].Export()

View File

@ -67,6 +67,7 @@ type Config struct {
DeviceKey string
ClientKey string
UserIdKey string
UserNameKey string
SessionProvider string
SessionTimeout int64
AuthFieldMessage string
@ -95,7 +96,7 @@ func initConfig(opt *gojs.Obj, logger *log.Logger, vm *goja.Runtime) {
s.SetWorkPath(u.String(startPath))
}
// 处理配置
serviceConfig = Config{"Session", "Device", "Client", "id", "", 3600, "auth failed", "verify failed", "too many requests", nil, "", 0, []string{}, map[string]string{}, map[string]string{}, map[string]string{}}
serviceConfig = Config{"Session", "Device", "Client", "id", "name", "", 3600, "auth failed", "verify failed", "too many requests", nil, "", 0, []string{}, map[string]string{}, map[string]string{}, map[string]string{}}
if errs := config.LoadConfig("service", &serviceConfig); len(errs) > 0 {
// panic(vm.NewGoError(errs[0]))
vm.SetData("_lastError", errs[0])
@ -134,7 +135,13 @@ func initConfig(opt *gojs.Obj, logger *log.Logger, vm *goja.Runtime) {
session = NewSession(sessionID, logger)
}
if userId, ok := session.data[serviceConfig.UserIdKey]; ok {
request.SetUserId(u.String(userId))
showUser := u.String(userId)
if serviceConfig.UserNameKey != "" {
if userName, ok := session.data[serviceConfig.UserNameKey]; ok {
showUser = fmt.Sprintf("%s(%s)", userName, userId)
}
}
request.SetUserId(showUser)
}
// 优先使用session中的authLevel
if authLevel > 0 {
@ -1012,7 +1019,7 @@ func makeRequestParams(args map[string]any, headers map[string]string, request *
if response != nil {
resp = &Response{
resp: response,
endCh: make(chan bool, 1),
endCh: nil,
Id: response.Id,
}
params["response"] = gojs.MakeMap(resp)
@ -1070,12 +1077,20 @@ func runAction(action goja.Callable, vm *goja.Runtime, thisArg goja.Value, args
// force set userId to vm
vmUserId := "_guest"
vmUserName := "Guest"
if session != nil {
if userId, ok := session.data[serviceConfig.UserIdKey]; ok {
vmUserId = u.String(userId)
vmUserName = vmUserId
}
if serviceConfig.UserNameKey != "" {
if userName, ok := session.data[serviceConfig.UserNameKey]; ok {
vmUserName = u.String(userName)
}
}
}
vm.SetData("userId", vmUserId)
vm.SetData("userName", vmUserName)
requestParams, resp := makeRequestParams(args, headers, request, response, client, caller, session, logger)
var r any
@ -1088,7 +1103,10 @@ func runAction(action goja.Callable, vm *goja.Runtime, thisArg goja.Value, args
logger.Error(err.Error())
}
if response != nil && r == nil && err == nil {
if resp.endCh != nil {
<-resp.endCh
resp.endCh = nil
}
r = resp.result
}
return r, err

View File

@ -112,6 +112,7 @@ export interface Config {
deviceKey: string // 标识设备ID的Key客户端没有传递时服务端自动生成Header的优先级高于Cookie默认为 Device 设置为空时表示不使用
clientKey: string // 标识客户端的Key默认为 Client对应的Header头为 ClientName 和 ClientVersion
userIdKey: string // session中userID的Key用于在日志中记录用户ID信息默认为 id
userNameKey: string // session中userName的Key用于在日志中记录用户名信息默认为 name
sessionProvider: string // 指定一个redis连接例如redis://:sskey加密的密码@127.0.0.1:6379/15默认使用内存存储
sessionTimeout: number // session过期时间单位 秒,默认为 3600秒
authFieldMessage: string | Object // 身份验证失败时的消息,默认为 auth failed可以设置对象来返回JSON可以使用模版 {{TARGET_AUTHLEVEL}}、{{USER_AUTHLEVEL}}
@ -208,7 +209,7 @@ export interface Session {
get: (...keys: string[]) => any | Object
remove: (...keys: string[]) => void
setAuthLevel: (authLevel: number) => void
save: () => void
save: (values?: Object) => boolean
}
export interface Caller {
@ -279,6 +280,7 @@ export interface Response {
sendFile: (contentType: string, filename: string) => void
downloadFile: (contentType: string, filename: string, data: any) => void
location: (url: string) => void
makeAsync: () => void
end: (data: any) => void
}

View File

@ -174,6 +174,12 @@ func (session *Session) AuthFuncs(argsIn goja.FunctionCall, vm *goja.Runtime) go
}
func (session *Session) Save(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm)
if len(args.Arguments) > 0 && args.Arguments[0].ExportType().Kind() == reflect.Map {
for key, value := range args.Map(0) {
session.data[key] = value
}
}
if session.conn == nil {
now := time.Now().Unix()
session.data["_time"] = now
@ -188,10 +194,10 @@ func (session *Session) Save(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Va
if clearTimeDiff > 60 {
go clearMemorySession()
}
return vm.ToValue(true)
} else {
session.conn.SETEX("SESS_"+session.id, int(sessionTimeout), session.data)
return vm.ToValue(session.conn.SETEX("SESS_"+session.id, int(sessionTimeout), session.data))
}
return nil
}
func clearMemorySession() {