feat 历史记录

This commit is contained in:
2026-01-14 18:15:36 +08:00
parent 313a93702e
commit 636008b97d
16 changed files with 58 additions and 66 deletions

View File

@@ -3,7 +3,7 @@ package app
import ( import (
"git.hlsq.asia/mmorpg/service-common/net/grpc/service" "git.hlsq.asia/mmorpg/service-common/net/grpc/service"
"git.hlsq.asia/mmorpg/service-gateway/config" "git.hlsq.asia/mmorpg/service-gateway/config"
"git.hlsq.asia/mmorpg/service-gateway/internal/grpc_server/server" "git.hlsq.asia/mmorpg/service-gateway/internal/grpc_server"
) )
// ModuleGrpcServer Grpc服务模块 // ModuleGrpcServer Grpc服务模块
@@ -16,7 +16,7 @@ func (m *ModuleGrpcServer) init() error {
} }
func (m *ModuleGrpcServer) start() error { func (m *ModuleGrpcServer) start() error {
m.server = server.NewServer(config.Get().Serve.Grpc.TTL) m.server = grpc_server.NewServer(config.Get().Serve.Grpc.TTL)
m.server.Init(config.Get().Serve.Grpc.Address, config.Get().Serve.Grpc.Port) m.server.Init(config.Get().Serve.Grpc.Address, config.Get().Serve.Grpc.Port)
return nil return nil
} }

View File

@@ -39,4 +39,5 @@ serve:
auth: auth:
secret: "bMa3mU4oCsX2KBex5o7GzwSnACpumFq3SdlDXYZgVTU=" secret: "bMa3mU4oCsX2KBex5o7GzwSnACpumFq3SdlDXYZgVTU="
expire: 259200 shortExpire: 60
longExpire: 10080

View File

@@ -14,8 +14,9 @@ type Config struct {
} }
type AuthConfig struct { type AuthConfig struct {
Secret string `yaml:"secret"` Secret string `yaml:"secret"`
Expire int64 `yaml:"expire"` ShortExpire int64 `yaml:"shortExpire"`
LongExpire int64 `yaml:"longExpire"`
} }
var cfg *Config var cfg *Config

View File

@@ -39,4 +39,5 @@ serve:
auth: auth:
secret: "bMa3mU4oCsX2KBex5o7GzwSnACpumFq3SdlDXYZgVTU=" secret: "bMa3mU4oCsX2KBex5o7GzwSnACpumFq3SdlDXYZgVTU="
expire: 259200 shortExpire: 15
longExpire: 10080

2
go.mod
View File

@@ -4,7 +4,7 @@ go 1.23.1
require ( require (
bou.ke/monkey v1.0.2 bou.ke/monkey v1.0.2
git.hlsq.asia/mmorpg/service-common v0.0.0-20260113095415-34b2e45e3d50 git.hlsq.asia/mmorpg/service-common v0.0.0-20260114100922-695f5e7b0497
github.com/alicebob/miniredis/v2 v2.35.0 github.com/alicebob/miniredis/v2 v2.35.0
github.com/gin-contrib/cors v1.7.6 github.com/gin-contrib/cors v1.7.6
github.com/gin-gonic/gin v1.11.0 github.com/gin-gonic/gin v1.11.0

2
go.sum
View File

@@ -2,8 +2,6 @@ bou.ke/monkey v1.0.2 h1:kWcnsrCNUatbxncxR/ThdYqbytgOIArtYWqcQLQzKLI=
bou.ke/monkey v1.0.2/go.mod h1:OqickVX3tNx6t33n1xvtTtu85YN5s6cKwVug+oHMaIA= bou.ke/monkey v1.0.2/go.mod h1:OqickVX3tNx6t33n1xvtTtu85YN5s6cKwVug+oHMaIA=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
git.hlsq.asia/mmorpg/service-common v0.0.0-20260113095415-34b2e45e3d50 h1:T0JZl2N+HMYRgyifEGFXD2y1MZOuoAS1xjnIg/JLGwM=
git.hlsq.asia/mmorpg/service-common v0.0.0-20260113095415-34b2e45e3d50/go.mod h1:xv6m1I2jUA6mudKVznygpnzMoshBQarthHD1QnkW4qc=
github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI= github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI=

View File

@@ -15,14 +15,6 @@ const (
MaxQueueUpSize = 100 // 最大排队人数 MaxQueueUpSize = 100 // 最大排队人数
) )
// PublicPaths 不需要鉴权的接口,硬编码注册
var PublicPaths = []string{
"/user/info",
"/qgdzs/get_question",
"/qgdzs/answer_question",
"/qgdzs/get_all_category",
}
var ( var (
OnlineUsersGauge prometheus.Gauge OnlineUsersGauge prometheus.Gauge
) )

View File

@@ -1,4 +1,4 @@
package server package grpc_server
import ( import (
"context" "context"

View File

@@ -1,4 +1,4 @@
package server package grpc_server
import ( import (
"git.hlsq.asia/mmorpg/service-common/discover/common" "git.hlsq.asia/mmorpg/service-common/discover/common"

View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"git.hlsq.asia/mmorpg/service-common/db/redis" "git.hlsq.asia/mmorpg/service-common/db/redis"
"git.hlsq.asia/mmorpg/service-common/log" "git.hlsq.asia/mmorpg/service-common/log"
"git.hlsq.asia/mmorpg/service-common/net/grpc/service" "git.hlsq.asia/mmorpg/service-common/net/grpc/grpc_client"
"git.hlsq.asia/mmorpg/service-common/net/http/http_resp" "git.hlsq.asia/mmorpg/service-common/net/http/http_resp"
"git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb" "git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb"
"git.hlsq.asia/mmorpg/service-common/utils" "git.hlsq.asia/mmorpg/service-common/utils"
@@ -36,7 +36,7 @@ func Login(c *gin.Context) {
http_resp.JsonBadRequest(c) http_resp.JsonBadRequest(c)
return return
} }
client, err := service.UserNewClientLB() client, err := grpc_client.UserNewClientLB()
if err != nil { if err != nil {
log.Errorf("Login UserNewClientLB error: %v", err) log.Errorf("Login UserNewClientLB error: %v", err)
http_resp.JsonOK(c, http_resp.Error(http_resp.Failed)) http_resp.JsonOK(c, http_resp.Error(http_resp.Failed))
@@ -97,11 +97,11 @@ func RefreshToken(c *gin.Context) {
} }
claims, err := utils.ParseToken(req.RefreshToken, config.Get().Auth.Secret) claims, err := utils.ParseToken(req.RefreshToken, config.Get().Auth.Secret)
if err != nil { if err != nil {
http_resp.JsonOK(c, http_resp.Error(http_resp.TokenInvalid)) http_resp.JsonUnauthorized(c)
return return
} }
if redis.GetClient().Get(c, fmt.Sprintf(global.KeyGatewayRefreshToken, claims.USN)).Val() != req.RefreshToken { if redis.GetClient().Get(c, fmt.Sprintf(global.KeyGatewayRefreshToken, claims.USN)).Val() != req.RefreshToken {
http_resp.JsonOK(c, http_resp.Error(http_resp.TokenInvalid)) http_resp.JsonUnauthorized(c)
return return
} }
at, rt, err := genToken(c, claims.USN) at, rt, err := genToken(c, claims.USN)
@@ -118,11 +118,11 @@ func RefreshToken(c *gin.Context) {
} }
func genToken(ctx context.Context, usn string) (string, string, error) { func genToken(ctx context.Context, usn string) (string, string, error) {
at, err := genTokenOne(ctx, global.KeyGatewayAccessToken, usn, 2*time.Hour) at, err := genTokenOne(ctx, global.KeyGatewayAccessToken, usn, time.Duration(config.Get().Auth.ShortExpire)*time.Minute)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
rt, err := genTokenOne(ctx, global.KeyGatewayRefreshToken, usn, 3*24*time.Hour) rt, err := genTokenOne(ctx, global.KeyGatewayRefreshToken, usn, time.Duration(config.Get().Auth.LongExpire)*time.Minute)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
@@ -130,7 +130,7 @@ func genToken(ctx context.Context, usn string) (string, string, error) {
} }
func genTokenOne(ctx context.Context, key string, usn string, ttl time.Duration) (string, error) { func genTokenOne(ctx context.Context, key string, usn string, ttl time.Duration) (string, error) {
token, err := utils.GenToken(usn, config.Get().Auth.Secret, time.Duration(config.Get().Auth.Expire)*time.Second) token, err := utils.GenToken(usn, config.Get().Auth.Secret, ttl)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@@ -5,7 +5,7 @@ import (
"context" "context"
"fmt" "fmt"
"git.hlsq.asia/mmorpg/service-common/db/redis" "git.hlsq.asia/mmorpg/service-common/db/redis"
"git.hlsq.asia/mmorpg/service-common/net/grpc/service" "git.hlsq.asia/mmorpg/service-common/net/grpc/grpc_client"
"git.hlsq.asia/mmorpg/service-common/net/http/http_resp" "git.hlsq.asia/mmorpg/service-common/net/http/http_resp"
"git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb" "git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb"
"git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb/mocks" "git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb/mocks"
@@ -50,10 +50,10 @@ func (ts *LoginTestSuite) TestLogin() {
}) })
ts.Run("UserNewClientLB Failed", func() { ts.Run("UserNewClientLB Failed", func() {
monkey.Patch(service.UserNewClientLB, func() (grpc_pb.UserClient, error) { monkey.Patch(grpc_client.UserNewClientLB, func() (grpc_pb.UserClient, error) {
return nil, assert.AnError return nil, assert.AnError
}) })
defer monkey.Unpatch(service.UserNewClientLB) defer monkey.Unpatch(grpc_client.UserNewClientLB)
w, c := utils.CreateTestContext("POST", "/", &LoginReq{ w, c := utils.CreateTestContext("POST", "/", &LoginReq{
Phone: "13800000000", Phone: "13800000000",
@@ -68,13 +68,13 @@ func (ts *LoginTestSuite) TestLogin() {
defer ctrl.Finish() defer ctrl.Finish()
client := mocks.NewMockUserClient(ctrl) client := mocks.NewMockUserClient(ctrl)
client.EXPECT(). client.EXPECT().
Login(gomock.Any(), gomock.Any()). PhoneLogin(gomock.Any(), gomock.Any()).
Return(nil, fmt.Errorf("gRPC failed")) Return(nil, fmt.Errorf("gRPC failed"))
monkey.Patch(service.UserNewClientLB, func() (grpc_pb.UserClient, error) { monkey.Patch(grpc_client.UserNewClientLB, func() (grpc_pb.UserClient, error) {
return client, nil return client, nil
}) })
defer monkey.Unpatch(service.UserNewClientLB) defer monkey.Unpatch(grpc_client.UserNewClientLB)
w, c := utils.CreateTestContext("POST", "/", &LoginReq{ w, c := utils.CreateTestContext("POST", "/", &LoginReq{
Phone: "13800000000", Phone: "13800000000",
@@ -89,13 +89,13 @@ func (ts *LoginTestSuite) TestLogin() {
defer ctrl.Finish() defer ctrl.Finish()
client := mocks.NewMockUserClient(ctrl) client := mocks.NewMockUserClient(ctrl)
client.EXPECT(). client.EXPECT().
Login(gomock.Any(), gomock.Any()). PhoneLogin(gomock.Any(), gomock.Any()).
Return(&grpc_pb.LoginResp{USN: "1", Name: "hh"}, nil) Return(&grpc_pb.PhoneLoginResp{USN: "1", Name: "hh"}, nil)
monkey.Patch(service.UserNewClientLB, func() (grpc_pb.UserClient, error) { monkey.Patch(grpc_client.UserNewClientLB, func() (grpc_pb.UserClient, error) {
return client, nil return client, nil
}) })
defer monkey.Unpatch(service.UserNewClientLB) defer monkey.Unpatch(grpc_client.UserNewClientLB)
w, c := utils.CreateTestContext("POST", "/", &LoginReq{ w, c := utils.CreateTestContext("POST", "/", &LoginReq{
Phone: "13800000000", Phone: "13800000000",

View File

@@ -4,8 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"git.hlsq.asia/mmorpg/service-common/db/redis" "git.hlsq.asia/mmorpg/service-common/db/redis"
"git.hlsq.asia/mmorpg/service-common/net/grpc/service" "git.hlsq.asia/mmorpg/service-common/net/grpc/grpc_client"
"git.hlsq.asia/mmorpg/service-common/net/grpc/stream_client"
"git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb" "git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb"
"git.hlsq.asia/mmorpg/service-common/proto/ss/ss_pb" "git.hlsq.asia/mmorpg/service-common/proto/ss/ss_pb"
"git.hlsq.asia/mmorpg/service-gateway/internal/global" "git.hlsq.asia/mmorpg/service-gateway/internal/global"
@@ -55,7 +54,7 @@ func (c *Client) handle(event Event) {
} }
func (c *Client) onEnter(msg *ss_pb.C2S_EnterInstance) { func (c *Client) onEnter(msg *ss_pb.C2S_EnterInstance) {
client, err := service.SceneNewClientLB() client, err := grpc_client.SceneNewClientLB()
if err != nil { if err != nil {
c.logger.Errorf("SceneNewClient err: %v", err) c.logger.Errorf("SceneNewClient err: %v", err)
return return
@@ -79,7 +78,7 @@ func (c *Client) onLeave() {
if c.SceneSID == "" { if c.SceneSID == "" {
return return
} }
client, err := service.SceneNewClient(c.SceneSID) client, err := grpc_client.SceneNewClient(c.SceneSID)
if err != nil { if err != nil {
c.logger.Errorf("SceneNewClient err: %v", err) c.logger.Errorf("SceneNewClient err: %v", err)
return return
@@ -98,7 +97,7 @@ func (c *Client) onAction(msg *ss_pb.C2S_Action) {
if c.SceneSID == "" { if c.SceneSID == "" {
return return
} }
if err := stream_client.SendMessageToScene(c.SceneSID, stream_client.FunAction, &grpc_pb.ActionReq{ if err := grpc_client.SendMessageToScene(c.SceneSID, grpc_client.FunAction, &grpc_pb.ActionReq{
UniqueNo: c.UniqueNo, UniqueNo: c.UniqueNo,
USN: c.USN, USN: c.USN,
Action: int32(msg.Action), Action: int32(msg.Action),
@@ -107,5 +106,6 @@ func (c *Client) onAction(msg *ss_pb.C2S_Action) {
SkillID: msg.SkillID, SkillID: msg.SkillID,
}); err != nil { }); err != nil {
c.logger.Errorf("send action err: %v", err) c.logger.Errorf("send action err: %v", err)
return
} }
} }

View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"git.hlsq.asia/mmorpg/service-common/db/redis" "git.hlsq.asia/mmorpg/service-common/db/redis"
"git.hlsq.asia/mmorpg/service-common/log" "git.hlsq.asia/mmorpg/service-common/log"
"git.hlsq.asia/mmorpg/service-common/net/grpc/service" "git.hlsq.asia/mmorpg/service-common/net/grpc/grpc_client"
"git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb" "git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb"
"git.hlsq.asia/mmorpg/service-common/proto/ss/ss_pb" "git.hlsq.asia/mmorpg/service-common/proto/ss/ss_pb"
"git.hlsq.asia/mmorpg/service-gateway/internal/global" "git.hlsq.asia/mmorpg/service-gateway/internal/global"
@@ -162,7 +162,7 @@ func (l *Login) CheckOnline(user *User) string {
// KickUser 把玩家踢下线 // KickUser 把玩家踢下线
func (l *Login) KickUser(gatewaySID string, usn string) bool { func (l *Login) KickUser(gatewaySID string, usn string) bool {
gc, err := service.GatewayNewClient(gatewaySID) gc, err := grpc_client.GatewayNewClient(gatewaySID)
if err != nil { if err != nil {
log.Errorf("KickUser cannot find gateway client: %v, sid: %v", err, gatewaySID) log.Errorf("KickUser cannot find gateway client: %v, sid: %v", err, gatewaySID)
return false return false

View File

@@ -5,7 +5,6 @@ import (
"git.hlsq.asia/mmorpg/service-common/net/http/http_resp" "git.hlsq.asia/mmorpg/service-common/net/http/http_resp"
"git.hlsq.asia/mmorpg/service-common/utils" "git.hlsq.asia/mmorpg/service-common/utils"
"git.hlsq.asia/mmorpg/service-gateway/config" "git.hlsq.asia/mmorpg/service-gateway/config"
"git.hlsq.asia/mmorpg/service-gateway/internal/global"
"github.com/gin-contrib/cors" "github.com/gin-contrib/cors"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"go.uber.org/zap" "go.uber.org/zap"
@@ -43,14 +42,13 @@ func ginLogger(logger *zap.SugaredLogger) gin.HandlerFunc {
func authJwt() gin.HandlerFunc { func authJwt() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
// 如果是Public接口有Token就读没有就算了 pList := strings.SplitN(c.Request.URL.Path, "/", 4)
public := false if len(pList) < 4 || pList[2] == "" {
for _, path := range global.PublicPaths { http_resp.JsonNotFound(c)
if strings.HasPrefix(c.Request.URL.Path, path) { return
public = true
break
}
} }
// 如果是Public接口有Token就读没有就算了
public := pList[2] == "open"
token := strings.TrimPrefix(c.GetHeader("Authorization"), "Bearer ") token := strings.TrimPrefix(c.GetHeader("Authorization"), "Bearer ")
if token == "" { if token == "" {
@@ -58,16 +56,14 @@ func authJwt() gin.HandlerFunc {
c.Next() c.Next()
return return
} }
http_resp.AbortUnauthorized(c) http_resp.JsonUnauthorized(c)
c.Abort()
return return
} }
claims, err := utils.ParseToken(token, config.Get().Auth.Secret) claims, err := utils.ParseToken(token, config.Get().Auth.Secret)
if err != nil { if err != nil {
if public { http_resp.JsonUnauthorized(c)
c.Next() c.Abort()
return
}
http_resp.AbortUnauthorized(c)
return return
} }

View File

@@ -3,7 +3,7 @@ package http_gateway
import ( import (
"context" "context"
"git.hlsq.asia/mmorpg/service-common/log" "git.hlsq.asia/mmorpg/service-common/log"
"git.hlsq.asia/mmorpg/service-common/net/grpc/service" "git.hlsq.asia/mmorpg/service-common/net/grpc/grpc_client"
"git.hlsq.asia/mmorpg/service-common/net/http/http_resp" "git.hlsq.asia/mmorpg/service-common/net/http/http_resp"
"git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb" "git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb"
"git.hlsq.asia/mmorpg/service-gateway/internal/handler/http_handler" "git.hlsq.asia/mmorpg/service-gateway/internal/handler/http_handler"
@@ -52,16 +52,18 @@ func InitRouter() *gin.Engine {
r.HandleMethodNotAllowed = true r.HandleMethodNotAllowed = true
r.NoMethod(func(c *gin.Context) { r.NoMethod(func(c *gin.Context) {
http_resp.JsonMethodNotAllowed(c) http_resp.JsonMethodNotAllowed(c)
c.Abort()
}) })
r.NoRoute(func(c *gin.Context) { r.NoRoute(func(c *gin.Context) {
http_resp.JsonNotFound(c) http_resp.JsonNotFound(c)
c.Abort()
}) })
initBaseRoute(r.Group("/"))
auth := r.Group("/") auth := r.Group("/")
auth.Use(authJwt()) auth.Use(authJwt())
// 网关
initBaseRoute(auth)
// 用户中心 // 用户中心
initUserPath(auth) initUserPath(auth)
// 奇怪的知识-服务端 // 奇怪的知识-服务端
@@ -72,13 +74,13 @@ func InitRouter() *gin.Engine {
func initBaseRoute(r *gin.RouterGroup) { func initBaseRoute(r *gin.RouterGroup) {
g := r.Group("/gw") g := r.Group("/gw")
g.POST("/login", http_handler.Login) g.POST("/open/login", http_handler.Login)
g.POST("/refresh_token", http_handler.RefreshToken) g.POST("/open/refresh_token", http_handler.RefreshToken)
} }
func initUserPath(r *gin.RouterGroup) { func initUserPath(r *gin.RouterGroup) {
g := r.Group("/user") g := r.Group("/user")
client, err := service.UserNewClientLB() client, err := grpc_client.UserNewClientLB()
if err != nil { if err != nil {
log.Errorf("get user conn failed: %v", err) log.Errorf("get user conn failed: %v", err)
return return
@@ -95,7 +97,7 @@ func initUserPath(r *gin.RouterGroup) {
func initQgdzsPath(r *gin.RouterGroup) { func initQgdzsPath(r *gin.RouterGroup) {
g := r.Group("/qgdzs") g := r.Group("/qgdzs")
client, err := service.QgdzsNewClientLB() client, err := grpc_client.QgdzsNewClientLB()
if err != nil { if err != nil {
log.Errorf("get qgdzs conn failed: %v", err) log.Errorf("get qgdzs conn failed: %v", err)
return return

View File

@@ -28,8 +28,9 @@ func (ts *TestSuite) SetupSuite() {
}, },
}, },
Auth: &config.AuthConfig{ Auth: &config.AuthConfig{
Secret: "test", Secret: "test",
Expire: 259200, ShortExpire: 15,
LongExpire: 10080,
}, },
}) })