Documentation
¶
Index ¶
- Constants
- Variables
- func AppendBodyMessage(path, data, nonce string, time, plan, usr int64) []byte
- func CheckPublicKey(c cache.Cache, requestObject *PublicKey, cipher crypto.Cipher) error
- func DigestBodyMessage(path, data, nonce string, time, plan, usr int64) []byte
- func ErrorMsgToLang(ctx *Context, msg string, args ...string) string
- func HKDFKey(shared []byte, nonce string) ([]byte, error)
- func JsonBodyRequiresOuterSignature(plan int64, plan2KeyBootstrap bool) bool
- func NewGracefulListener(address string, maxWaitTime time.Duration) (net.Listener, error)
- func PlanRequiresOuterSignature(plan int64) bool
- func PutJsonBody(body *JsonBody)
- func PutJsonResp(resp *JsonResp)
- func PutMessageHandler(mh *MessageHandler)
- func SignAndDigestBodyMessage(path, data, nonce string, time, plan, usr int64, key []byte) ([]byte, []byte)
- func SignBodyMessage(path, data, nonce string, time, plan, usr int64, key []byte) []byte
- type CacheAware
- type ConfigValidator
- type Configs
- type ConnectionContext
- func (cc *ConnectionContext) GetRawTokenBytes() []byte
- func (cc *ConnectionContext) GetTokenSecret() []byte
- func (cc *ConnectionContext) GetUserID() int64
- func (cc *ConnectionContext) GetUserIDInt64() int64
- func (cc *ConnectionContext) GetUserIDString() string
- func (cc *ConnectionContext) Parser(body []byte, dst interface{}) error
- type ConnectionManager
- func (cm *ConnectionManager) Add(conn *DevConn) error
- func (cm *ConnectionManager) CleanupAll()
- func (cm *ConnectionManager) CleanupExpired(timeoutSeconds int64) int
- func (cm *ConnectionManager) Count() int
- func (cm *ConnectionManager) Get(subject, deviceKey string) *DevConn
- func (cm *ConnectionManager) GetAllSubjectDevices() map[string][]string
- func (cm *ConnectionManager) GetSubjectDevices(subject string) map[string][]string
- func (cm *ConnectionManager) HealthCheck() map[string]int
- func (cm *ConnectionManager) Remove(subject, deviceKey string) *DevConn
- func (cm *ConnectionManager) RemoveByConn(conn *DevConn) bool
- func (cm *ConnectionManager) SendToSubject(subject, router string, data interface{}) error
- type ConnectionUniquenessMode
- type Context
- func (self *Context) AddStorage(k string, v interface{})
- func (self *Context) Authenticated() bool
- func (self *Context) Bytes(data []byte) error
- func (self *Context) CheckOuterSign(cipher crypto.Cipher, msg, sign []byte) (crypto.Cipher, error)
- func (self *Context) ClientDevice() string
- func (self *Context) ClientLanguage() string
- func (self *Context) CreatePublicKey() (*PublicKey, error)
- func (self *Context) DelStorage(k string)
- func (self *Context) GetCacheObject() (cache.Cache, error)
- func (self *Context) GetHeader(key string) string
- func (self *Context) GetHmac256Sign(d, n string, t, p, u int64, key []byte) []byte
- func (self *Context) GetJwtConfig() jwt.JwtConfig
- func (self *Context) GetPostBody() string
- func (self *Context) GetRawTokenBytes() []byte
- func (self *Context) GetStorage(k string) interface{}
- func (self *Context) GetTokenSecret() []byte
- func (self *Context) GetUserIDInt64() int64
- func (self *Context) GetUserIDString() string
- func (self *Context) Handle() error
- func (self *Context) Json(data interface{}) error
- func (self *Context) NoBody() error
- func (self *Context) Parser(dst interface{}) error
- func (self *Context) RemoteIP() string
- func (self *Context) Text(data string) error
- type DevConn
- type ErrorHandle
- type ErrorHandler
- type Filter
- type FilterObject
- type GatewayRateLimiterFilter
- type GracefulListener
- type Handle
- type HeartbeatService
- type HookNode
- type HttpLog
- type HttpNode
- func (self *HttpNode) AddCipher(key int64, cipher crypto.Cipher) error
- func (self *HttpNode) AddErrorHandle(errorHandle func(ctx *Context, throw ex.Throw) error) error
- func (self *HttpNode) AddFilter(object *FilterObject)
- func (self *HttpNode) AddJwtConfig(config jwt.JwtConfig) error
- func (self *HttpNode) AddLanguage(langDs, filePath string) error
- func (self *HttpNode) AddLanguageByJson(langDs string, bs []byte) error
- func (self *HttpNode) AddLocalCache(cacheAware CacheAware)
- func (self *HttpNode) AddRedisCache(cacheAware CacheAware)
- func (self *HttpNode) AddRoleRealm(roleRealm func(ctx *Context) (*Permission, error)) error
- func (self *HttpNode) Bytes(ctx *Context, data []byte) error
- func (self *HttpNode) ClearFilterChain()
- func (self *HttpNode) DELETE(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
- func (self *HttpNode) Empty(ctx *Context) error
- func (self *HttpNode) EnableECC(enable bool)
- func (self *HttpNode) GET(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
- func (self *HttpNode) HEAD(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
- func (self *HttpNode) Json(ctx *Context, data interface{}) error
- func (self *HttpNode) OPTIONS(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
- func (self *HttpNode) PATCH(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
- func (self *HttpNode) POST(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
- func (self *HttpNode) PUT(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
- func (self *HttpNode) SetAcceptTimeout(timeout int64)
- func (self *HttpNode) SetDefaultMethodRateLimiter(option rate.Option)
- func (self *HttpNode) SetDynamicSecretKey(key string)
- func (self *HttpNode) SetGatewayRateLimiter(option rate.Option)
- func (self *HttpNode) SetLengthCheck(bodyLen, tokenLen, codeLen int)
- func (self *HttpNode) SetMethodRateLimiterByPath(path string, option rate.Option)
- func (self *HttpNode) SetSystem(name, version string)
- func (self *HttpNode) SetUserRateLimiter(option rate.Option)
- func (self *HttpNode) StartServer(addr string)
- func (self *HttpNode) Text(ctx *Context, data string) error
- type JsonBody
- func (v JsonBody) MarshalEasyJSON(w *jwriter.Writer)
- func (v JsonBody) MarshalJSON() ([]byte, error)
- func (self *JsonBody) ParseData(dst interface{}) error
- func (self *JsonBody) RawData() []byte
- func (v *JsonBody) UnmarshalEasyJSON(l *jlexer.Lexer)
- func (v *JsonBody) UnmarshalJSON(data []byte) error
- type JsonResp
- type MessageHandler
- type ParameterFilter
- type Permission
- type PostHandle
- type PostHandleFilter
- type PrivateKey
- type PublicKey
- type RenderHandleFilter
- type Response
- type RoleFilter
- type RouteInfo
- type RouterConfig
- type SessionFilter
- type System
- type UserRateLimiterFilter
- type WebSocketMetrics
- type WsEventHandler
- func (h *WsEventHandler) OnClose(socket *gws.Conn, err error)
- func (h *WsEventHandler) OnMessage(socket *gws.Conn, message *gws.Message)
- func (h *WsEventHandler) OnOpen(socket *gws.Conn)
- func (h *WsEventHandler) OnPing(socket *gws.Conn, payload []byte)
- func (h *WsEventHandler) OnPong(socket *gws.Conn, payload []byte)
- type WsMessagePostFilter
- type WsMessagePreFilter
- type WsServer
- func (self *WsServer) AddCipher(usr int64, cipher crypto.Cipher) error
- func (self *WsServer) AddJwtConfig(config jwt.JwtConfig) error
- func (self *WsServer) AddLocalCache(cacheAware CacheAware)
- func (self *WsServer) AddRedisCache(cacheAware CacheAware)
- func (s *WsServer) AddRouter(path string, handle Handle, routerConfig *RouterConfig) error
- func (s *WsServer) AddWsPostFilter(f WsMessagePostFilter)
- func (s *WsServer) AddWsPreFilter(f WsMessagePreFilter)
- func (s *WsServer) BuildPlan2KeyResponse(req *PublicKey) (*PublicKey, error)
- func (s *WsServer) CheckOuterSign(cipher crypto.Cipher, msg, sign []byte) (crypto.Cipher, error)
- func (self *WsServer) GetCacheObject() (cache.Cache, error)
- func (s *WsServer) GetConnManager() *ConnectionManager
- func (s *WsServer) GetConnectionManager() *ConnectionManager
- func (s *WsServer) GetMetrics() *WebSocketMetrics
- func (s *WsServer) LogMetrics()
- func (s *WsServer) NewPool(maxConn, limit, bucket, ping int) error
- func (s *WsServer) NewPoolWithIdleTimeout(maxConn, limit, bucket, ping, idleTimeoutSeconds int) error
- func (s *WsServer) SetAuthTimeWindowSeconds(seconds int64)
- func (s *WsServer) SetIdleTimeout(timeout time.Duration)
- func (s *WsServer) SetMaxBodyLen(n int)
- func (s *WsServer) SetParallelEnabled(enabled bool)
- func (s *WsServer) SetPlan2SharedKeyTTLSeconds(seconds int64)
- func (s *WsServer) SetPushKeyProvider(provider func(subject string) string)
- func (s *WsServer) SetValidateTokenPerMessage(validate bool)
- func (s *WsServer) StartWebsocket(addr string) error
- func (s *WsServer) StopWebsocket() (err error)
- func (s *WsServer) StopWebsocketWithTimeout(timeout time.Duration) error
Constants ¶
const ( GatewayRateLimiterFilterName = "GatewayRateLimiterFilter" // 网关限流过滤器 ParameterFilterName = "ParameterFilter" // 参数解析过滤器 SessionFilterName = "SessionFilter" // 会话验证过滤器 UserRateLimiterFilterName = "UserRateLimiterFilter" // 用户限流过滤器 RoleFilterName = "RoleFilter" // 角色权限过滤器 PostHandleFilterName = "PostHandleFilter" // 后置处理过滤器 RenderHandleFilterName = "RenderHandleFilter" // 响应渲染过滤器 )
过滤器名称常量定义 用于标识不同类型的过滤器,方便配置和管理
const ( UTF8 = "UTF-8" ANDROID = "android" IOS = "ios" WEB = "web" TEXT_PLAIN = "text/plain; charset=utf-8" APPLICATION_JSON = "application/json; charset=utf-8" NO_BODY = "no_body" GET = "GET" POST = "POST" PUT = "PUT" PATCH = "PATCH" DELETE = "DELETE" HEAD = "HEAD" OPTIONS = "OPTIONS" Authorization = "Authorization" Cipher = "Cipher" SharedInfo = "freego-ecdh-aes-gcm" )
const ( DefaultWsRoute = "/ws" // 默认WebSocket路由路径 DefaultWsMaxBodyLen = 1024 * 1024 // 默认单条消息体最大 1MB,可通过 WsServer.SetMaxBodyLen 覆盖 )
WebSocket服务器实现
错误类型约定:
- 协议错误(客户端请求不合法、鉴权失败等):使用 ex.Throw{Code, Msg[, Err]},便于上层按 HTTP 状态码处理或回写。
- 配置/内部错误(校验配置、连接池、调用方参数等):使用 utils.Error,仅作日志或返回给调用方,无状态码需求。
WebSocket专用常量
Variables ¶
var ( MAX_BODY_LEN = 200000 // 最大参数值长度 MAX_TOKEN_LEN = 2048 // JWT 等常规 Authorization 上限;Plan2 见 maxAuthorizationHeaderLen MAX_CODE_LEN = 1024 // 最大Code值长度 )
Functions ¶
func AppendBodyMessage ¶ added in v1.1.0
func CheckPublicKey ¶ added in v1.1.0
func DigestBodyMessage ¶ added in v1.1.12
DigestBodyMessage returns SHA-256 digest of canonical body message.
func ErrorMsgToLang ¶ added in v1.0.129
func JsonBodyRequiresOuterSignature ¶ added in v1.1.22
JsonBodyRequiresOuterSignature 是否校验/生成 JsonBody.Valid(ML-DSA)。 plan2KeyBootstrap:WebSocket Plan2 /key 握手使用 p=0,但仍须 ML-DSA。
func NewGracefulListener ¶
NewGracefulListener 创建一个新的优雅关闭监听器 返回 (监听器, 错误),避免直接panic,让调用者处理初始化失败
func PlanRequiresOuterSignature ¶ added in v1.1.22
PlanRequiresOuterSignature Plan2 业务报文(p=2)需要 ML-DSA 外层签名。
func PutJsonBody ¶ added in v1.1.0
func PutJsonBody(body *JsonBody)
PutJsonBody 将JsonBody对象放回对象池 注意:放回前需要重置对象字段,避免数据污染
func PutJsonResp ¶ added in v1.1.0
func PutJsonResp(resp *JsonResp)
PutJsonResp 将JsonResp对象放回对象池 注意:放回前需要重置对象字段,避免数据污染
func PutMessageHandler ¶ added in v1.1.0
func PutMessageHandler(mh *MessageHandler)
PutMessageHandler 将MessageHandler对象放回池中,并重置其字段
Types ¶
type Configs ¶ added in v1.0.113
type Configs struct {
// contains filtered or unexported fields
}
Configs 结构体 - 88字节 (4个字段,8字节对齐,无填充) 排列优化:大字段优先,string放在最后利用16字节对齐
type ConnectionContext ¶ added in v1.1.0
type ConnectionContext struct {
Subject *jwt.Subject
WsConn *gws.Conn // WebSocket 连接(gws)
DevConn *DevConn
Server *WsServer
RouterConfig *RouterConfig // 路由配置
Path string // WebSocket连接的路径
RawToken []byte // 原始JWT token字节,用于签名验证
// contains filtered or unexported fields
}
ConnectionContext 每个 WebSocket 连接的上下文(与 HTTP 的 node.Context 不同,不含 JsonBody)。 单帧协议体使用 Process(..., jb) 的池化 *JsonBody,避免与 ParallelEnabled 下的并发收包共享指针。
func (*ConnectionContext) GetRawTokenBytes ¶ added in v1.1.0
func (cc *ConnectionContext) GetRawTokenBytes() []byte
GetRawTokenBytes 获取原始JWT token字节
func (*ConnectionContext) GetTokenSecret ¶ added in v1.1.0
func (cc *ConnectionContext) GetTokenSecret() []byte
GetTokenSecret 获取WebSocket连接的 token 派生密钥(每次调用重新派生,不缓存)。 为保证安全需在用毕后 DIC.ClearData(secret);为此接受每次 HMAC 派生的性能损耗。
func (*ConnectionContext) GetUserID ¶ added in v1.1.0
func (cc *ConnectionContext) GetUserID() int64
GetUserID 获取用户ID int64类型
func (*ConnectionContext) GetUserIDInt64 ¶ added in v1.1.19
func (cc *ConnectionContext) GetUserIDInt64() int64
GetUserIDInt64 获取用户ID int64类型
func (*ConnectionContext) GetUserIDString ¶ added in v1.1.0
func (cc *ConnectionContext) GetUserIDString() string
GetUserIDString 获取用户ID string类型
func (*ConnectionContext) Parser ¶ added in v1.1.12
func (cc *ConnectionContext) Parser(body []byte, dst interface{}) error
Parser 解析 WebSocket 业务数据并填充 common.BaseReq 上下文。
type ConnectionManager ¶ added in v1.1.0
type ConnectionManager struct {
// contains filtered or unexported fields
}
ConnectionManager 连接管理器:线程安全的连接管理,支持广播、按 subject 推送、过期清理。
设计要点: - conns:二级 map subject -> deviceKey -> *DevConn,deviceKey 由 mode 决定(SubjectUnique 时为 sub,SubjectDeviceUnique 时为 sub_dev)。 - totalConn:原子计数,用于限流、Count()、以及 CleanupExpired/sendToSubjectByJsonResp 的 slice 预分配容量,避免在 RLock 内做重逻辑。 - 所有"收集 conn 再关闭/发送"的路径均在 RLock 内只收集指针,在锁外执行 I/O,避免持锁时间过长。 - reverseIndex:反向索引 *gws.Conn -> reverseIndexEntry,用于 O(1) 复杂度的 RemoveByConn(适合连接数 > 10000 的场景)。
func NewConnectionManager ¶ added in v1.1.0
func NewConnectionManager(maxConn int, mode ConnectionUniquenessMode, broadcastKeyProvider func(subject string) string) *ConnectionManager
NewConnectionManager 创建连接管理器
func (*ConnectionManager) Add ¶ added in v1.1.0
func (cm *ConnectionManager) Add(conn *DevConn) error
Add 添加连接 Add 将连接加入管理器。根据连接唯一性模式决定策略: - SubjectUnique: 替换同 subject 的所有连接,只保留一个。 - SubjectDeviceUnique: 替换同 subject+device 的连接,允许多设备同时在线。 设备键格式:subject_device (如: user123_web, user123_app)
设计要点:若存在旧连接,先从 map 移除并减 totalConn,再在 goroutine 中 closeConn,避免锁内 I/O 阻塞。
func (*ConnectionManager) CleanupAll ¶ added in v1.1.0
func (cm *ConnectionManager) CleanupAll()
CleanupAll 关闭所有连接。先 RLock 内收集全部 conn 指针并预分配 slice,锁外再统一 closeConn。 设计要点:先发送关闭帧,OnClose 回调会负责从 map 中移除(避免重复移除)。
func (*ConnectionManager) CleanupExpired ¶ added in v1.1.0
func (cm *ConnectionManager) CleanupExpired(timeoutSeconds int64) int
CleanupExpired 清理空闲超过 timeoutSeconds 的连接。
设计要点: - 在 RLock 内仅收集过期 conn 指针(LastSeen 为原子读无锁),RUnlock 后再 closeConn,避免持锁做 I/O。 - toClose 按 totalConn 预分配容量,减少 append 扩容与 GC。 - 超时判断依赖 DevConn.Last(每次收包/心跳 UpdateLast),由 HeartbeatService 按 idleTimeout 周期性调用。 - 先发送关闭帧,OnClose 回调会负责从 map 中移除(避免重复移除)。
func (*ConnectionManager) Count ¶ added in v1.1.0
func (cm *ConnectionManager) Count() int
Count 获取当前连接数
func (*ConnectionManager) Get ¶ added in v1.1.0
func (cm *ConnectionManager) Get(subject, deviceKey string) *DevConn
Get 获取指定连接
func (*ConnectionManager) GetAllSubjectDevices ¶ added in v1.1.3
func (cm *ConnectionManager) GetAllSubjectDevices() map[string][]string
GetAllSubjectDevices 获取所有用户连接subject
func (*ConnectionManager) GetSubjectDevices ¶ added in v1.1.3
func (cm *ConnectionManager) GetSubjectDevices(subject string) map[string][]string
GetSubjectDevices
func (*ConnectionManager) HealthCheck ¶ added in v1.1.0
func (cm *ConnectionManager) HealthCheck() map[string]int
HealthCheck 健康检查:返回每个 subject 的连接数。 活性由 LastSeen 与 CleanupExpired 维护。
func (*ConnectionManager) Remove ¶ added in v1.1.0
func (cm *ConnectionManager) Remove(subject, deviceKey string) *DevConn
Remove 移除连接(不关闭,仅从管理器移除)
func (*ConnectionManager) RemoveByConn ¶ added in v1.1.6
func (cm *ConnectionManager) RemoveByConn(conn *DevConn) bool
RemoveByConn 按连接指针从管理器中移除该连接。 设计要点: - 使用 reverseIndex 反向索引实现 O(1) 查找,避免遍历所有连接(适合连接数 > 10000 的场景)。 - 必须用指针精确匹配,避免“新连接已替换旧连接”时误把新连接从 map 删掉。 - 关闭由 closeConnFromLoop 等调用方负责。 返回是否成功移除(若连接已被替换则未找到,返回 false)。
func (*ConnectionManager) SendToSubject ¶ added in v1.1.0
func (cm *ConnectionManager) SendToSubject(subject, router string, data interface{}) error
SendToSubject 按 subject 推送消息(subject=="" 时为全量广播)。
调用约定: - subject: 目标用户标识;传空字符串表示发送给全部在线连接。 - router: 业务路由,必填;客户端通常按该路由分发消息。 - data: 业务载荷,必填;内部会先 JSON 序列化再 Base64 封装到 JsonResp.Data。
安全与协议: - 本方法会统一构造 JsonResp(Code=300, Message="push", Plan=0)。 - 签名密钥来自 broadcastKeyProvider(subject),支持按用户/广播动态取密钥。 - 未配置可用密钥时返回错误,避免发送未签名或弱签名数据。
type ConnectionUniquenessMode ¶ added in v1.1.0
type ConnectionUniquenessMode int
ConnectionUniquenessMode 连接唯一性模式 用于控制WebSocket连接的唯一性策略
const ( // SubjectUnique 仅Subject唯一,一个用户只能有一个连接 // 适用于单设备应用场景,如移动端App SubjectUnique ConnectionUniquenessMode = iota // SubjectDeviceUnique Subject+Device唯一,一个用户可以在多个设备上连接 // 适用于多设备场景,如Web、App、PC同时在线 SubjectDeviceUnique )
type Context ¶
type Context struct {
// 16字节string字段组 (2个字段,32字节)
Method string // 16字节 (8+8) - string字段
Path string // 16字节 (8+8) - string字段
System *System // 8字节 - 指针
RequestCtx *fasthttp.RequestCtx // 8字节 - 指针
Subject *jwt.Subject // 8字节 - 指针
JsonBody *JsonBody // 8字节 - 指针
Response *Response // 8字节 - 指针
RouterConfig *RouterConfig // 8字节 - 指针
// 8字节函数指针字段组 (5个字段,40字节)
RedisCacheAware func(ds ...string) (cache.Cache, error) // 8字节 - 函数指针
LocalCacheAware func(ds ...string) (cache.Cache, error) // 8字节 - 函数指针
// 8字节其他字段组 (3个字段)
PQCipher map[int64]crypto.Cipher // Plan2:ML-DSA-87 外层签
Storage map[string]interface{}
// contains filtered or unexported fields
}
Context 结构体 - 184字节 (19个字段,8字节对齐,0字节填充) 排列优化:按字段大小和类型分组,16字节string字段在前,8字节指针/函数/map字段居中,bool字段在后
func (*Context) AddStorage ¶
func (*Context) Authenticated ¶
func (*Context) CheckOuterSign ¶ added in v1.1.10
CheckOuterSign 校验外层数字签名(经 cipher.Verify;ML-DSA-87)。
func (*Context) ClientDevice ¶ added in v1.0.104
func (*Context) ClientLanguage ¶ added in v1.0.107
func (*Context) CreatePublicKey ¶ added in v1.1.0
func (*Context) DelStorage ¶ added in v1.0.3
func (*Context) GetCacheObject ¶ added in v1.1.0
func (*Context) GetHmac256Sign ¶
func (*Context) GetJwtConfig ¶
func (*Context) GetPostBody ¶ added in v1.0.134
func (*Context) GetRawTokenBytes ¶ added in v1.1.0
func (*Context) GetStorage ¶
func (*Context) GetTokenSecret ¶
func (*Context) GetUserIDInt64 ¶ added in v1.1.19
GetUserIDInt64 获取用户ID int64类型, 零值认为是无用户信息
func (*Context) GetUserIDString ¶ added in v1.1.19
GetUserIDString 获取用户ID string类型
type DevConn ¶ added in v1.0.146
type DevConn struct {
Sub string
Dev string
Last int64 // 最后活跃时间戳,原子读写,供 CleanupExpired 无锁判断
Conn *gws.Conn // WebSocket 连接(gws)
// contains filtered or unexported fields
}
DevConn 设备连接实体:存储单连接的核心信息。
设计要点: - Last:使用原子读写(UpdateLast 写、LastSeen 读),使 CleanupExpired 遍历时无需加锁。 - 多 goroutine 并发 Send 依赖 gws.Conn.WriteMessage 的线程安全(库内 channel + 单写);不再额外加 sendMu,避免与 ParallelEnabled 下多回包场景无谓争用。 - closed:与 CleanupExpired / 踢线等路径上的 WriteClose 配合,Send 内先读后写;与 WriteClose 之间无应用层全局锁(历来如此)。 - closeOnce:保证 Close() 只执行一次,避免重复关闭导致 panic。
func (*DevConn) LastSeen ¶ added in v1.1.6
LastSeen 返回最近一次活跃时间。原子读、无锁,供 CleanupExpired 在 RLock 内批量调用。
func (*DevConn) Send ¶ added in v1.1.0
Send 向连接写入一条文本消息。 并发安全由 gws.Conn.WriteMessage 保证;closed 仅作快速失败,与 WriteClose 竞态时以 gws 返回错误为准。
func (*DevConn) UpdateLast ¶ added in v1.1.6
func (dc *DevConn) UpdateLast()
UpdateLast 更新连接最后活跃时间。原子写,无锁,便于消息循环中高频调用且不影响 CleanupExpired 遍历。
type ErrorHandler ¶ added in v1.1.0
type ErrorHandler struct {
}
ErrorHandler WebSocket错误处理器(统一错误处理)
type FilterObject ¶
type FilterObject struct {
Name string // 16字节 (8+8) - string字段
Filter Filter // 16字节 (8+8) - interface{}字段
MatchPattern []string // 24字节 (8+8+8) - slice字段
Order int // 8字节 - int字段放在最后
}
FilterObject 结构体 - 64字节 (4个字段,8字节对齐,优化排列减少填充) 排列优化:大字段优先,相同大小字段分组
type GatewayRateLimiterFilter ¶
type GatewayRateLimiterFilter struct{} // 网关级限流过滤器
过滤器结构体定义 实现Filter接口的DoFilter方法,按照职责分离的原则处理不同的过滤逻辑
type GracefulListener ¶
type GracefulListener struct {
// contains filtered or unexported fields
}
GracefulListener 支持优雅关闭的TCP监听器,关闭时会等待现有连接处理完毕
func (*GracefulListener) Close ¶
func (ln *GracefulListener) Close() error
Close 关闭监听器并等待所有活跃连接处理完毕(优雅关闭) 1. 先关闭底层监听器,停止接受新连接 2. 等待现有连接关闭,超时则返回错误
func (*GracefulListener) CloseWithTimeout ¶ added in v1.1.0
func (ln *GracefulListener) CloseWithTimeout(timeout time.Duration) error
CloseWithTimeout 带超时的优雅关闭
type Handle ¶ added in v1.0.146
type Handle func(ctx context.Context, connCtx *ConnectionContext, body []byte) (interface{}, error)
核心类型定义 Handle 业务处理函数,返回 nil 则不回复。 对象池约束:*JsonResp 由 replyData Put 回池;*JsonBody 在 WebSocket 路径为每条消息的栈上/池对象(Process 的 jb),不得异步持有。 WS 业务 Handle 须在返回前结束对 bizData/connCtx 的使用;若启动 goroutine,不得捕获池化 JsonBody 指针。
type HeartbeatService ¶ added in v1.1.0
type HeartbeatService struct {
// contains filtered or unexported fields
}
HeartbeatService 心跳服务:gws 已内置 ping/pong,此服务仅用于定期清理过期连接
func NewHeartbeatService ¶ added in v1.1.0
func NewHeartbeatService(interval, timeout time.Duration, manager *ConnectionManager) *HeartbeatService
func (*HeartbeatService) Start ¶ added in v1.1.0
func (hs *HeartbeatService) Start()
func (*HeartbeatService) Stop ¶ added in v1.1.0
func (hs *HeartbeatService) Stop()
type HookNode ¶
type HookNode struct {
Context *Context // 8字节 - 指针字段
// contains filtered or unexported fields
}
HookNode 结构体 - 32字节 (2个字段,8字节对齐,无填充) 排列优化:指针字段在前,slice字段在后
filters:须在进程初始化阶段完成 AddFilter;StartServer 内会经 createFilterChain 整体替换为排序后的链。 约定:监听并处理请求期间不得再 AddFilter(无并发 append 与 DoFilter 遍历同一切片的安全保证)。
type HttpLog ¶
type HttpLog struct {
Method string // 请求方法 - 16字节 (8+8)
LogNo string // 日志唯一标记 - 16字节 (8+8)
CreateAt int64 // 日志创建时间 - 8字节
UpdateAt int64 // 日志完成时间 - 8字节
CostMill int64 // 业务耗时,毫秒 - 8字节
}
HttpLog 结构体 - 64字节 (5个字段,8字节对齐,无填充) 排列优化:string字段在前,int64字段连续排列
type HttpNode ¶
type HttpNode struct {
HookNode
// contains filtered or unexported fields
}
func (*HttpNode) AddCipher ¶ added in v1.0.72
AddCipher 注册 Plan2(ML-DSA-87)外层验签:须 crypto.CreateMLDSA87WithBase64(服务端 ML-DSA 私钥,该客户端 ML-DSA 公钥)。 与客户端 HttpSDK.SetMLDSA87Object 互为镜像;Plan0/Plan1 不使用外层 Valid 签名。
func (*HttpNode) AddErrorHandle ¶ added in v1.0.121
func (*HttpNode) AddFilter ¶
func (self *HttpNode) AddFilter(object *FilterObject)
AddFilter 追加自定义过滤器(按 Order 与内置过滤器合并排序见 StartServer 内 createFilterChain)。 使用约定:仅在服务监听前、初始化阶段调用;监听运行期间不得再调用,否则与并发请求执行 DoFilter 不安全。
func (*HttpNode) AddLanguage ¶ added in v1.0.107
func (*HttpNode) AddLanguageByJson ¶ added in v1.0.128
func (*HttpNode) AddLocalCache ¶ added in v1.1.0
func (self *HttpNode) AddLocalCache(cacheAware CacheAware)
AddLocalCache 增加本地缓存实例
func (*HttpNode) AddRedisCache ¶ added in v1.1.0
func (self *HttpNode) AddRedisCache(cacheAware CacheAware)
AddRedisCache 增加redis缓存实例
func (*HttpNode) AddRoleRealm ¶ added in v1.0.115
func (self *HttpNode) AddRoleRealm(roleRealm func(ctx *Context) (*Permission, error)) error
func (*HttpNode) ClearFilterChain ¶
func (self *HttpNode) ClearFilterChain()
func (*HttpNode) DELETE ¶
func (self *HttpNode) DELETE(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
func (*HttpNode) GET ¶
func (self *HttpNode) GET(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
func (*HttpNode) HEAD ¶
func (self *HttpNode) HEAD(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
func (*HttpNode) OPTIONS ¶
func (self *HttpNode) OPTIONS(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
func (*HttpNode) PATCH ¶
func (self *HttpNode) PATCH(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
func (*HttpNode) POST ¶
func (self *HttpNode) POST(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
func (*HttpNode) PUT ¶
func (self *HttpNode) PUT(path string, handle func(ctx *Context) error, routerConfig *RouterConfig)
func (*HttpNode) SetAcceptTimeout ¶ added in v1.1.9
func (*HttpNode) SetDefaultMethodRateLimiter ¶ added in v1.1.0
func (*HttpNode) SetDynamicSecretKey ¶ added in v1.1.3
SetDynamicSecretKey 增加本地secret定义,最少24个字符长度
func (*HttpNode) SetGatewayRateLimiter ¶ added in v1.1.0
SetGatewayRateLimiter 设置网关级限流器配置 用于控制整个服务的全局请求频率,防止服务过载 option: 限流器配置,包含速率和桶容量等参数
func (*HttpNode) SetLengthCheck ¶ added in v1.1.0
func (*HttpNode) SetMethodRateLimiterByPath ¶ added in v1.1.0
SetMethodRateLimiterByPath 为特定路径设置方法级限流器
func (*HttpNode) SetUserRateLimiter ¶ added in v1.1.0
SetUserRateLimiter 设置用户级限流器配置 用于控制每个用户的请求频率,防止恶意用户刷接口 option: 限流器配置,通常设置较低的速率限制
func (*HttpNode) StartServer ¶
type JsonBody ¶
type JsonBody struct {
// 16字节字段组 (3个string字段,48字节)
Data string `json:"d"` // 16字节 (8+8) - string字段
Nonce string `json:"n"` // 16字节 (8+8) - string字段
Sign string `json:"s"` // 16字节 (8+8) - string字段
Valid string `json:"e"` // 16字节 (8+8) - string字段
Router string `json:"r"` // 16字节 (8+8) - string字段
// 8字节字段组 (2个int64字段,16字节)
Time int64 `json:"t"` // 8字节 - int64字段
Plan int64 `json:"p"` // 8字节 - 0.默认(登录状态) 1.AES(登录状态) 2.Plan2(ML-KEM+ML-DSA匿名)
User int64 `json:"u"` // 8字节 - 客户端ID
}
JsonBody 结构体 - 64字节 (5个字段,8字节对齐,无填充) 排列优化:string字段组在前(48字节),int64字段组在后(16字节)
func (JsonBody) MarshalEasyJSON ¶ added in v1.1.0
MarshalEasyJSON supports easyjson.Marshaler interface
func (JsonBody) MarshalJSON ¶ added in v1.1.0
MarshalJSON supports json.Marshaler interface
func (*JsonBody) UnmarshalEasyJSON ¶ added in v1.1.0
UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (*JsonBody) UnmarshalJSON ¶ added in v1.1.0
UnmarshalJSON supports json.Unmarshaler interface
type JsonResp ¶
type JsonResp struct {
// 16字节字段组 (4个string字段,64字节)
Message string `json:"m"` // 16字节 (8+8) - string字段
Data string `json:"d"` // 16字节 (8+8) - string字段
Nonce string `json:"n"` // 16字节 (8+8) - string字段
Sign string `json:"s"` // 16字节 (8+8) - string字段
Valid string `json:"e"` // 16字节 (8+8) - string字段
Router string `json:"r"` // 16字节 (8+8) - 路由字段,用于消息订阅
// 8字节字段组 (3个字段:1个int+2个int64,24字节)
Code int `json:"c"` // 8字节 - int字段
Time int64 `json:"t"` // 8字节 - int64字段
Plan int64 `json:"p"` // 8字节 - int64字段
}
JsonResp 结构体 - 96字节 (7个字段,8字节对齐,无填充) 排列优化:string字段组在前(64字节),int和int64字段组在后(32字节)
func (JsonResp) MarshalEasyJSON ¶ added in v1.1.0
MarshalEasyJSON supports easyjson.Marshaler interface
func (JsonResp) MarshalJSON ¶ added in v1.1.0
MarshalJSON supports json.Marshaler interface
func (*JsonResp) UnmarshalEasyJSON ¶ added in v1.1.0
UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (*JsonResp) UnmarshalJSON ¶ added in v1.1.0
UnmarshalJSON supports json.Unmarshaler interface
type MessageHandler ¶ added in v1.1.0
type MessageHandler struct {
// contains filtered or unexported fields
}
MessageHandler 消息处理器:统一处理消息校验、解码、路由
func GetMessageHandler ¶ added in v1.1.0
func GetMessageHandler(pqCipher map[int64]crypto.Cipher, handle Handle) *MessageHandler
GetMessageHandler 从池中获取一个MessageHandler对象
func (*MessageHandler) CheckOuterSign ¶ added in v1.1.10
CheckOuterSign 按用户 ID 取 ML-DSA Cipher 并校验外层签名。
func (*MessageHandler) Process ¶ added in v1.1.0
func (mh *MessageHandler) Process(connCtx *ConnectionContext, body []byte, jb *JsonBody) (crypto.Cipher, interface{}, error)
Process 处理单条 WS 文本帧。jb 为本条消息独占的 JsonBody(由调用方从池取出并在调用结束后 Put),不得与 connCtx 共享指针以免并发覆盖。
type ParameterFilter ¶
type ParameterFilter struct{} // 参数解析过滤器
type Permission ¶
type Permission struct {
MatchAll bool // true.满足所有权限角色才放行 - 1字节
NeedLogin bool // true.需要登录状态 - 1字节
HasRole []int64 // 拥有角色ID列表 - 24字节 (8+8+8)
NeedRole []int64 // 所需角色ID列表 - 24字节 (8+8+8)
}
Permission 结构体 - 48字节 (4个字段,8字节对齐,0字节填充) 排列优化:bool字段在前,slice字段连续排列,利用8字节对齐
type PostHandle ¶
type PostHandleFilter ¶
type PostHandleFilter struct{} // 后置处理过滤器
type PrivateKey ¶ added in v1.1.0
func (PrivateKey) MarshalEasyJSON ¶ added in v1.1.0
func (v PrivateKey) MarshalEasyJSON(w *jwriter.Writer)
MarshalEasyJSON supports easyjson.Marshaler interface
func (PrivateKey) MarshalJSON ¶ added in v1.1.0
func (v PrivateKey) MarshalJSON() ([]byte, error)
MarshalJSON supports json.Marshaler interface
func (*PrivateKey) UnmarshalEasyJSON ¶ added in v1.1.0
func (v *PrivateKey) UnmarshalEasyJSON(l *jlexer.Lexer)
UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (*PrivateKey) UnmarshalJSON ¶ added in v1.1.0
func (v *PrivateKey) UnmarshalJSON(data []byte) error
UnmarshalJSON supports json.Unmarshaler interface
type PublicKey ¶ added in v1.1.0
type PublicKey struct {
Key string `json:"key"` // 服务端临时公钥
Tag string `json:"tag"` // 客户端临时公钥
Noc string `json:"noc"` // 随机数
Sig string `json:"sig"` // 数据签名
Exp int64 `json:"exp"` // 有效时间,单位秒
Usr int64 `json:"usr"` // 客户端ID
}
func CreatePublicKey ¶ added in v1.1.0
func (PublicKey) MarshalEasyJSON ¶ added in v1.1.0
MarshalEasyJSON supports easyjson.Marshaler interface
func (PublicKey) MarshalJSON ¶ added in v1.1.0
MarshalJSON supports json.Marshaler interface
func (*PublicKey) UnmarshalEasyJSON ¶ added in v1.1.0
UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (*PublicKey) UnmarshalJSON ¶ added in v1.1.0
UnmarshalJSON supports json.Unmarshaler interface
type RenderHandleFilter ¶
type RenderHandleFilter struct{} // 响应渲染过滤器
type Response ¶
type Response struct {
Encoding string // 16字节 (8+8) - string字段
ContentType string // 16字节 (8+8) - string字段
ContentEntity interface{} // 16字节 (8+8) - interface{}字段
StatusCode int // 8字节 - int字段
ContentEntityByte bytes.Buffer // 24字节 - bytes.Buffer (包含内部字段)
}
Response 结构体 - 80字节 (5个字段,8字节对齐,0字节填充) 排列优化:string和interface{}字段在前,int字段和复杂类型字段在后
type RoleFilter ¶
type RoleFilter struct{} // 角色权限过滤器
type RouteInfo ¶ added in v1.1.0
type RouteInfo struct {
Handle Handle // 业务处理器
RouterConfig *RouterConfig // 路由配置
}
RouteInfo WebSocket路由信息结构体
type RouterConfig ¶
type RouterConfig struct {
Guest bool // 游客模式,原始请求 false.否 true.是 - 1字节
UsePlan2 bool // Plan2 匿名路由(ML-KEM+ML-DSA) false.否 true.是 - 1字节
KeyRoute bool // WebSocket plan2 key 路由(仅允许匿名 plan0)
LoginRoute bool // WebSocket plan2 login 路由(仅允许 plan2)
AesRequest bool // 请求是否必须AES加密 false.否 true.是 - 1字节
AesResponse bool // 响应是否必须AES加密 false.否 true.是 - 1字节
}
RouterConfig 结构体 - 4字节 (4个bool字段,1字节对齐) 排列优化:bool字段自然排列,无填充问题
type SessionFilter ¶
type SessionFilter struct{} // 会话验证过滤器
type System ¶ added in v1.0.116
type System struct {
Name string // 系统名 - 16字节 (8+8)
Version string // 系统版本 - 16字节 (8+8)
AcceptTimeout int64 // 超时主动断开客户端连接,秒 - 8字节
// contains filtered or unexported fields
}
System 结构体 - 40字节 (4个字段,8字节对齐,0字节填充) 排列优化:string字段在前,bool字段居中,int64字段在后,利用8字节对齐
type UserRateLimiterFilter ¶
type UserRateLimiterFilter struct{} // 用户级限流过滤器
type WebSocketMetrics ¶ added in v1.1.0
type WebSocketMetrics struct {
// contains filtered or unexported fields
}
WebSocketMetrics WebSocket监控指标
type WsEventHandler ¶ added in v1.1.12
type WsEventHandler struct {
// contains filtered or unexported fields
}
WsEventHandler gws 事件处理器:处理 WebSocket 连接的生命周期事件
func (*WsEventHandler) OnClose ¶ added in v1.1.12
func (h *WsEventHandler) OnClose(socket *gws.Conn, err error)
OnClose 连接关闭时的回调
func (*WsEventHandler) OnMessage ¶ added in v1.1.12
func (h *WsEventHandler) OnMessage(socket *gws.Conn, message *gws.Message)
OnMessage 收到消息时的回调
func (*WsEventHandler) OnOpen ¶ added in v1.1.12
func (h *WsEventHandler) OnOpen(socket *gws.Conn)
OnOpen 连接建立时的回调
type WsMessagePostFilter ¶ added in v1.1.21
type WsMessagePostFilter func(ctx context.Context, connCtx *ConnectionContext, jb *JsonBody, bizData []byte, reply interface{}, handleErr error) error
WsMessagePostFilter 在业务 Handle 返回之后、构造成功回包(replyData)之前执行。 handleErr 为 Handle 的 error;仅做日志时返回 nil。若 handleErr 为 nil 且本函数返回非 nil,则本条按错误处理。 handleErr 非 nil 时,本函数返回值被忽略。使用约定:仅在监听前 AddWsPostFilter。
type WsMessagePreFilter ¶ added in v1.1.21
type WsMessagePreFilter func(ctx context.Context, connCtx *ConnectionContext, jb *JsonBody, bizData []byte) error
WsMessagePreFilter 在单条 WS 业务消息已完成解密且路由命中之后、调用业务 Handle 之前执行。 返回非 nil 时终止本条处理(与 Handle 返回错误一致,不发送成功回包)。 使用约定:仅在 StartWebsocket 监听前 AddWsPreFilter;/ws/ping 与未命中路由不进入此前置链。
type WsServer ¶ added in v1.0.146
type WsServer struct {
// ECC和缓存配置(用于Plan 2)
// 8字节函数指针字段组 (5个字段,40字节)
PQCipher map[int64]crypto.Cipher // Plan2:ML-DSA-87
RedisCacheAware func(ds ...string) (cache.Cache, error) // 8字节 - 函数指针
LocalCacheAware func(ds ...string) (cache.Cache, error) // 8字节 - 函数指针
PushKeyProvider func(subject string) string // 推送签名密钥获取函数:subject=="" 表示全量广播
// contains filtered or unexported fields
}
WsServer WebSocket服务器核心结构体
func NewWsServer ¶ added in v1.1.0
func NewWsServer(connUniquenessMode ConnectionUniquenessMode) *WsServer
NewWsServer 创建WebSocket服务器 connUniquenessMode: 连接唯一性模式
- SubjectUnique: 一个用户只能有一个连接(适用于单设备应用)
- SubjectDeviceUnique: 一个用户可以在多个设备上连接(适用于多设备场景)
func (*WsServer) AddCipher ¶ added in v1.1.0
AddCipher 注册 Plan2 ML-DSA-87 验签(与 HttpNode.AddCipher 一致)。
func (*WsServer) AddJwtConfig ¶ added in v1.0.146
AddJwtConfig 添加JWT配置
func (*WsServer) AddLocalCache ¶ added in v1.1.0
func (self *WsServer) AddLocalCache(cacheAware CacheAware)
AddLocalCache 增加本地缓存实例
func (*WsServer) AddRedisCache ¶ added in v1.1.0
func (self *WsServer) AddRedisCache(cacheAware CacheAware)
AddRedisCache 增加redis缓存实例
func (*WsServer) AddRouter ¶ added in v1.0.146
func (s *WsServer) AddRouter(path string, handle Handle, routerConfig *RouterConfig) error
AddRouter 注册路由:path -> Handle。应在 StartWebsocket 之前完成所有注册。 不支持在服务启动后动态添加:消息循环中会无锁读 s.routes,动态添加会产生并发读写风险。
func (*WsServer) AddWsPostFilter ¶ added in v1.1.21
func (s *WsServer) AddWsPostFilter(f WsMessagePostFilter)
AddWsPostFilter 注册 WebSocket 业务后置过滤器(在 Handle 返回之后、replyData 之前执行)。 使用约定:仅在 StartWebsocket 监听前调用。
func (*WsServer) AddWsPreFilter ¶ added in v1.1.21
func (s *WsServer) AddWsPreFilter(f WsMessagePreFilter)
AddWsPreFilter 注册 WebSocket 业务前置过滤器(在解密完成且路由命中之后、Handle 之前执行)。 使用约定:仅在 StartWebsocket 监听前调用;监听运行期间不得再调用(与 HttpNode.AddFilter 一致)。
func (*WsServer) BuildPlan2KeyResponse ¶ added in v1.1.12
BuildPlan2KeyResponse 处理 plan2 的 /key 交换(ML-KEM + ML-DSA)。
func (*WsServer) CheckOuterSign ¶ added in v1.1.12
func (*WsServer) GetCacheObject ¶ added in v1.1.0
GetCacheObject 获取缓存对象
func (*WsServer) GetConnManager ¶ added in v1.1.0
func (s *WsServer) GetConnManager() *ConnectionManager
GetConnManager 获取连接管理器(用于测试)
func (*WsServer) GetConnectionManager ¶ added in v1.1.0
func (s *WsServer) GetConnectionManager() *ConnectionManager
GetConnectionManager 获取连接管理器(用于健康检查等操作)
func (*WsServer) GetMetrics ¶ added in v1.1.0
func (s *WsServer) GetMetrics() *WebSocketMetrics
GetMetrics 获取监控指标快照(所有计数器均用 atomic 读取)
func (*WsServer) LogMetrics ¶ added in v1.1.0
func (s *WsServer) LogMetrics()
LogMetrics 记录当前监控指标到日志
func (*WsServer) NewPool ¶ added in v1.0.146
maxConn = 300 // 允许的最大并发连接数 limit = 20 // 每秒允许的平均消息数(令牌桶速率) bucket = 100 // 令牌桶容量(突发消息缓冲) ping = 15 // 心跳间隔(秒)
func (*WsServer) NewPoolWithIdleTimeout ¶ added in v1.1.12
func (s *WsServer) NewPoolWithIdleTimeout(maxConn, limit, bucket, ping, idleTimeoutSeconds int) error
NewPoolWithIdleTimeout 创建连接池并设置心跳周期与空闲踢线时间(秒)。 idleTimeoutSeconds <= 0 时回退为 2 倍 ping。
func (*WsServer) SetAuthTimeWindowSeconds ¶ added in v1.1.12
SetAuthTimeWindowSeconds 设置请求时间窗(秒)。<=0 时忽略。
func (*WsServer) SetIdleTimeout ¶ added in v1.1.0
SetIdleTimeout 设置连接空闲超时时间
func (*WsServer) SetMaxBodyLen ¶ added in v1.1.6
SetMaxBodyLen 设置单条消息体最大长度(字节),需在 StartWebsocket 前调用
func (*WsServer) SetParallelEnabled ¶ added in v1.1.12
SetParallelEnabled 设置是否并行处理同一连接上的消息(需在 StartWebsocket 前调用)。 true 可提升吞吐;false 可保证单连接消息按处理顺序串行。
func (*WsServer) SetPlan2SharedKeyTTLSeconds ¶ added in v1.1.12
SetPlan2SharedKeyTTLSeconds 设置 plan2 临时共享密钥 TTL(秒)。<=0 时忽略。
func (*WsServer) SetPushKeyProvider ¶ added in v1.1.12
SetPushKeyProvider 设置推送签名密钥获取函数。subject=="" 表示全量广播。
func (*WsServer) SetValidateTokenPerMessage ¶ added in v1.1.6
SetValidateTokenPerMessage 设置是否在每条消息时校验 token 有效期(validWebSocketBody 内生效)。 false(默认):仅建连时校验,连接期间 token 过期不踢线,性能更好; true:每条消息校验 exp,过期即 401,适合强安全/合规场景。
func (*WsServer) StartWebsocket ¶ added in v1.0.146
func (*WsServer) StopWebsocket ¶ added in v1.1.0
StopWebsocket 停止WebSocket服务器