From f7f4beb57da45b63409ea05d6808967001a10fa6 Mon Sep 17 00:00:00 2001 From: zqj <582132116@qq.com> Date: Mon, 21 Feb 2022 12:30:02 +0800 Subject: [PATCH] 新增grpc平滑关闭,修复createrole的bug, 新增的函数 --- README.md | 6 +----- actions/accountaction.go | 2 +- actions/basic.go | 10 ++++++++-- actions/roleaction.go | 10 +++++----- actions/server.go | 20 ++++++++++---------- cmd/account.go | 16 ++++++++++++++-- cmd/game.go | 16 +++++++++++++--- components/db/mongo.go | 4 +--- components/etcd/etcd.go | 35 ++++++++++++++++++++--------------- models/role.go | 8 +++++--- protos | 2 +- test/client.go | 36 ++++++++++++++++++++---------------- utils/utils.go | 18 ++++++++---------- 13 files changed, 107 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 3e60aef..7ebca25 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,4 @@ $ make run 测试 ```shell $ make test -``` - - - - +``` \ No newline at end of file diff --git a/actions/accountaction.go b/actions/accountaction.go index f74268c..0664b08 100644 --- a/actions/accountaction.go +++ b/actions/accountaction.go @@ -60,7 +60,7 @@ func (s *AccountServer) CreateTokenHandler(ctx context.Context, in *pb.AccountIn Rsp: &pb.PubRsp{ Code: 0, }, - Token: utils.CreateToken(in), + Token: utils.CreateToken(m.AccountInfo), GameService: gameInfo, }, nil } diff --git a/actions/basic.go b/actions/basic.go index 7d3a9f7..b123bb4 100644 --- a/actions/basic.go +++ b/actions/basic.go @@ -2,15 +2,18 @@ package actions import ( "fmt" + "google.golang.org/grpc" "net" "pro2d/components/db" "pro2d/components/etcd" "pro2d/conf" + "pro2d/utils" ) type BasicServer struct { - SConf *conf.SConf + SConf *conf.SConf EtcdClient *etcd.EtcdClient + GrpcServer *grpc.Server } func NewServer() *BasicServer { @@ -34,5 +37,8 @@ func (b *BasicServer) Start(sConf *conf.SConf) (net.Listener, error) { return lis, err } -func (b *BasicServer) Close() { +func (b *BasicServer) Stop() { + utils.Sugar.Debugf("平滑关闭服务") + b.EtcdClient.Close() + b.GrpcServer.GracefulStop() } diff --git a/actions/roleaction.go b/actions/roleaction.go index 2913f02..7412672 100644 --- a/actions/roleaction.go +++ b/actions/roleaction.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "google.golang.org/grpc/metadata" + "pro2d/conf" "pro2d/models" "pro2d/protos/pb" "pro2d/utils" @@ -45,11 +46,9 @@ func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.Token) (*pb.R } ok, role := models.RoleExistByUid(account.Uid) if !ok { - *role.Role = pb.Role{ - Level: 0, - Device: account.Device, - Uid: account.Uid, - } + role = models.NewRole(conf.SnowFlack.NextVal()) + role.Role.Device = account.Device + role.Role.Uid = account.Uid role.Create() } @@ -67,6 +66,7 @@ func (s *GameServer) LoginHandler(ctx context.Context, in *pb.Token) (*pb.RoleRs if account == nil { return nil, fmt.Errorf("token is error") } + utils.Sugar.Debugf("login account: %v", account) ok, role := models.RoleExistByUid(account.Uid) if !ok { return &pb.RoleRsp{ diff --git a/actions/server.go b/actions/server.go index 1314c51..59b1de3 100644 --- a/actions/server.go +++ b/actions/server.go @@ -39,20 +39,20 @@ func (s *AccountServer)Start() error { models.InitAccountServerModels() //new一个grpc - gs := grpc.NewServer(grpc.UnaryInterceptor(AccountServerInterceptor)) + s.GrpcServer = grpc.NewServer(grpc.UnaryInterceptor(AccountServerInterceptor)) - pb.RegisterAccountServer(gs, s) - reflection.Register(gs) //在给定的gRPC服务器上注册服务器反射服务 + pb.RegisterAccountServer(s.GrpcServer, s) + reflection.Register(s.GrpcServer) //在给定的gRPC服务器上注册服务器反射服务 // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。 // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。 utils.Sugar.Debugf("Start AccountServer listening on %d", conf.GlobalConf.AccountConf.Port) - return gs.Serve(lis) + return s.GrpcServer.Serve(lis) } func (s *AccountServer)Stop() { - s.BasicServer.Close() + s.BasicServer.Stop() } type GameServer struct{ @@ -83,17 +83,17 @@ func (s *GameServer)Start() error { models.InitGameServerModels() //new一个grpc - gs := grpc.NewServer(grpc.UnaryInterceptor(GameServerInterceptor)) + s.GrpcServer = grpc.NewServer(grpc.UnaryInterceptor(GameServerInterceptor)) - pb.RegisterGameServer(gs, s) - reflection.Register(gs) //在给定的gRPC服务器上注册服务器反射服务 + pb.RegisterGameServer(s.GrpcServer, s) + reflection.Register(s.GrpcServer) //在给定的gRPC服务器上注册服务器反射服务 // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。 // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。 utils.Sugar.Debugf("Start GameServer listening on %d", conf.GlobalConf.GameConf.Port) - return gs.Serve(lis) + return s.GrpcServer.Serve(lis) } func (s *GameServer)Stop() { - s.BasicServer.Close() + s.BasicServer.Stop() } \ No newline at end of file diff --git a/cmd/account.go b/cmd/account.go index bfcf2c4..15ca376 100644 --- a/cmd/account.go +++ b/cmd/account.go @@ -1,17 +1,29 @@ package main import ( + "os" + "os/signal" "pro2d/actions" "pro2d/utils" + "syscall" ) func main() { err := make(chan error) + stopChan := make(chan os.Signal) + signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) + server := actions.NewAccountServer() go func() { - defer server.Stop() err <- server.Start() }() - utils.Sugar.Errorf("server error: %v", <- err) + + select { + case e := <- err: + utils.Sugar.Errorf("game server error: %v", e) + case <-stopChan: + // 平滑关闭服务 + server.Stop() + } } diff --git a/cmd/game.go b/cmd/game.go index 3366c52..45825fd 100644 --- a/cmd/game.go +++ b/cmd/game.go @@ -1,19 +1,29 @@ package main import ( + "os" + "os/signal" "pro2d/actions" "pro2d/utils" + "syscall" ) func main() { err := make(chan error) - + stopChan := make(chan os.Signal) + signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) server := actions.NewGameServer() go func() { - defer server.Stop() err <- server.Start() }() - utils.Sugar.Errorf("server error: %v", <- err) + + select { + case e := <- err: + utils.Sugar.Errorf("game server error: %v", e) + case <-stopChan: + // 平滑关闭服务 + server.Stop() + } } diff --git a/components/db/mongo.go b/components/db/mongo.go index c7a86c6..4c56db2 100644 --- a/components/db/mongo.go +++ b/components/db/mongo.go @@ -9,7 +9,6 @@ import ( "go.mongodb.org/mongo-driver/mongo/readpref" "go.mongodb.org/mongo-driver/x/bsonx" "pro2d/utils" - "reflect" "sort" "strconv" "time" @@ -96,8 +95,7 @@ func NewMongoColl(key string, schema interface{}) *MgoColl { } func FindOne(pri interface{}, schema interface{}) error { - s := reflect.TypeOf(schema) - r := MongoDatabase.Collection(s.Name()).FindOne(context.TODO(), pri) + r := MongoDatabase.Collection(utils.GetCollName(schema)).FindOne(context.TODO(), pri) return r.Decode(schema) } diff --git a/components/etcd/etcd.go b/components/etcd/etcd.go index e0fd291..9df28e0 100644 --- a/components/etcd/etcd.go +++ b/components/etcd/etcd.go @@ -17,6 +17,7 @@ func NewEtcdClient(conf *conf.Etcd) *EtcdClient { cli, err := clientv3.New(clientv3.Config{ Endpoints: conf.Endpoints, DialTimeout: time.Duration(conf.DialTimeout) * time.Second, + Logger: utils.Logger, }) if err != nil { utils.Sugar.Errorf("etcd init err: %v", err) @@ -49,25 +50,25 @@ func (e *EtcdClient)PutWithLeasePrefix(prefix, key, val string, ttl int64) error return err } - _, err = lease.KeepAlive(context.TODO(), leaseResp.ID) + keepRespChan, err := lease.KeepAlive(context.TODO(), leaseResp.ID) if err != nil { utils.Sugar.Errorf("keepalive err: %v", err) return err } - //go func() { - // for { - // select { - // case keepResp := <-keepRespChan: - // if keepRespChan == nil { - // fmt.Println("租约已经失效") - // goto END - // } else { //每秒会续租一次,所以就会受到一次应答 - // fmt.Println("收到自动续租应答:", keepResp.ID) - // } - // } - // } - // END: - //}() + go func() { + for { + select { + case _ = <-keepRespChan: + if keepRespChan == nil { + fmt.Println("租约已经失效") + goto END + } else { //每秒会续租一次,所以就会受到一次应答 + //fmt.Println("收到自动续租应答:", keepResp.ID) + } + } + } + END: + }() return nil } @@ -99,4 +100,8 @@ func (e *EtcdClient)GetByPrefix(prefix string) map[string]string { m[string(v.Key)] = string(v.Value) } return m +} + +func (e *EtcdClient)Close() { + e.etcd.Close() } \ No newline at end of file diff --git a/models/role.go b/models/role.go index 2c87529..655f905 100644 --- a/models/role.go +++ b/models/role.go @@ -22,9 +22,11 @@ func RoleExistByUid(uid string) (bool, *RoleModel){ if err := db.FindOne(db.GetBsonM("uid", uid), data); err != nil { return false, nil } - m := NewRole(data.Id) - m.Load() - return true, m + + return true, &RoleModel{ + MgoColl: db.NewMongoColl(strconv.Itoa(int(data.Id)), data), + Role: data, + } } func NewRole(id int64) *RoleModel { diff --git a/protos b/protos index 3df1fd7..a01eb6e 160000 --- a/protos +++ b/protos @@ -1 +1 @@ -Subproject commit 3df1fd713f54812f465bbc704c6677aec3ccbe92 +Subproject commit a01eb6ede9a8e3f9d5ec30bf41e9f6e0f4f9ee1f diff --git a/test/client.go b/test/client.go index fd8bd76..b73cd72 100644 --- a/test/client.go +++ b/test/client.go @@ -35,6 +35,7 @@ func Login(loginUri, token string) { defer gameConn.Close() client:= pb.NewGameClient(gameConn) + var role *pb.Role loginRsp, err := client.LoginHandler(context.Background(), &pb.Token{ Token: token, }) @@ -43,17 +44,20 @@ func Login(loginUri, token string) { utils.Sugar.Errorf("login error: %v", err) return } + role = loginRsp.Role - print(loginRsp) - - createRole, err := client.CreateRoleHandler(context.Background(), &pb.Token{Token: token}) - if err != nil { - utils.Sugar.Errorf("create role err: %v", err) - return + if loginRsp.Rsp.Code != 0 { + utils.Sugar.Debugf("login rsp: %v", loginRsp.Rsp.Msg) + createRole, err := client.CreateRoleHandler(context.Background(), &pb.Token{Token: token}) + if err != nil { + utils.Sugar.Errorf("create role err: %v", err) + return + } + utils.Sugar.Debug("create role rsp: ", createRole.Rsp.Code, createRole.Rsp.Msg) + role = createRole.Role } - print(createRole) - utils.Sugar.Debug("login rsp: ", createRole.Rsp.Code, createRole.Rsp.Msg) + utils.Sugar.Debugf("login successful role: %v", role) } func main() { @@ -64,11 +68,11 @@ func main() { } defer conn.Close() c := pb.NewAccountClient(conn) - err = Register(c,"17683852936", "123456") - if err != nil { - utils.Sugar.Errorf("register err: %v", err) - return - } + //err = Register(c,"17683852936", "123456") + //if err != nil { + // utils.Sugar.Errorf("register err: %v", err) + // return + //} rsp, err := c.CreateTokenHandler(context.Background(), &pb.AccountInfo{ Phone: "17683852936", Password: "123456", @@ -84,7 +88,7 @@ func main() { return } - Login(rsp.GameService.Address, rsp.Token) - - + if len(rsp.GameService) >0 { + Login(rsp.GameService[0].Address, rsp.Token) + } } diff --git a/utils/utils.go b/utils/utils.go index b663ab2..6e06ab5 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,20 +5,21 @@ import ( "strings" ) -func GetCollName(schema interface{}) string { +func GetSchemaType(schema interface{}) reflect.Type { s := reflect.TypeOf(schema) if s.Kind() == reflect.Ptr { s = reflect.TypeOf(schema).Elem() } + return s +} - return strings.ToLower(s.Name()) +func GetCollName(schema interface{}) string { + return strings.ToLower(GetSchemaType(schema).Name()) } func GetPriKey(schema interface{}) string { - s := reflect.TypeOf(schema) - if s.Kind() == reflect.Ptr { - s = reflect.TypeOf(schema).Elem() - } + s := GetSchemaType(schema) + var pri string for i := 0; i < s.NumField(); i++ { if s.Field(i).Tag.Get("pri") == "1" { @@ -30,10 +31,7 @@ func GetPriKey(schema interface{}) string { } func FindIndex(schema interface{}) (string, []string){ - s := reflect.TypeOf(schema) - if s.Kind() == reflect.Ptr { - s = reflect.TypeOf(schema).Elem() - } + s := GetSchemaType(schema) var index []string for i := 0; i < s.NumField(); i++ { -- libgit2 0.21.2