Commit f7f4beb57da45b63409ea05d6808967001a10fa6
1 parent
286f6dbe
新增grpc平滑关闭,修复createrole的bug, 新增的函数
Showing
13 changed files
with
107 additions
and
76 deletions
Show diff stats
README.md
actions/accountaction.go
actions/basic.go
| ... | ... | @@ -2,15 +2,18 @@ package actions |
| 2 | 2 | |
| 3 | 3 | import ( |
| 4 | 4 | "fmt" |
| 5 | + "google.golang.org/grpc" | |
| 5 | 6 | "net" |
| 6 | 7 | "pro2d/components/db" |
| 7 | 8 | "pro2d/components/etcd" |
| 8 | 9 | "pro2d/conf" |
| 10 | + "pro2d/utils" | |
| 9 | 11 | ) |
| 10 | 12 | |
| 11 | 13 | type BasicServer struct { |
| 12 | - SConf *conf.SConf | |
| 14 | + SConf *conf.SConf | |
| 13 | 15 | EtcdClient *etcd.EtcdClient |
| 16 | + GrpcServer *grpc.Server | |
| 14 | 17 | } |
| 15 | 18 | |
| 16 | 19 | func NewServer() *BasicServer { |
| ... | ... | @@ -34,5 +37,8 @@ func (b *BasicServer) Start(sConf *conf.SConf) (net.Listener, error) { |
| 34 | 37 | return lis, err |
| 35 | 38 | } |
| 36 | 39 | |
| 37 | -func (b *BasicServer) Close() { | |
| 40 | +func (b *BasicServer) Stop() { | |
| 41 | + utils.Sugar.Debugf("平滑关闭服务") | |
| 42 | + b.EtcdClient.Close() | |
| 43 | + b.GrpcServer.GracefulStop() | |
| 38 | 44 | } | ... | ... |
actions/roleaction.go
| ... | ... | @@ -5,6 +5,7 @@ import ( |
| 5 | 5 | "errors" |
| 6 | 6 | "fmt" |
| 7 | 7 | "google.golang.org/grpc/metadata" |
| 8 | + "pro2d/conf" | |
| 8 | 9 | "pro2d/models" |
| 9 | 10 | "pro2d/protos/pb" |
| 10 | 11 | "pro2d/utils" |
| ... | ... | @@ -45,11 +46,9 @@ func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.Token) (*pb.R |
| 45 | 46 | } |
| 46 | 47 | ok, role := models.RoleExistByUid(account.Uid) |
| 47 | 48 | if !ok { |
| 48 | - *role.Role = pb.Role{ | |
| 49 | - Level: 0, | |
| 50 | - Device: account.Device, | |
| 51 | - Uid: account.Uid, | |
| 52 | - } | |
| 49 | + role = models.NewRole(conf.SnowFlack.NextVal()) | |
| 50 | + role.Role.Device = account.Device | |
| 51 | + role.Role.Uid = account.Uid | |
| 53 | 52 | role.Create() |
| 54 | 53 | |
| 55 | 54 | } |
| ... | ... | @@ -67,6 +66,7 @@ func (s *GameServer) LoginHandler(ctx context.Context, in *pb.Token) (*pb.RoleRs |
| 67 | 66 | if account == nil { |
| 68 | 67 | return nil, fmt.Errorf("token is error") |
| 69 | 68 | } |
| 69 | + utils.Sugar.Debugf("login account: %v", account) | |
| 70 | 70 | ok, role := models.RoleExistByUid(account.Uid) |
| 71 | 71 | if !ok { |
| 72 | 72 | return &pb.RoleRsp{ | ... | ... |
actions/server.go
| ... | ... | @@ -39,20 +39,20 @@ func (s *AccountServer)Start() error { |
| 39 | 39 | models.InitAccountServerModels() |
| 40 | 40 | |
| 41 | 41 | //new一个grpc |
| 42 | - gs := grpc.NewServer(grpc.UnaryInterceptor(AccountServerInterceptor)) | |
| 42 | + s.GrpcServer = grpc.NewServer(grpc.UnaryInterceptor(AccountServerInterceptor)) | |
| 43 | 43 | |
| 44 | - pb.RegisterAccountServer(gs, s) | |
| 45 | - reflection.Register(gs) //在给定的gRPC服务器上注册服务器反射服务 | |
| 44 | + pb.RegisterAccountServer(s.GrpcServer, s) | |
| 45 | + reflection.Register(s.GrpcServer) //在给定的gRPC服务器上注册服务器反射服务 | |
| 46 | 46 | |
| 47 | 47 | // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。 |
| 48 | 48 | // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。 |
| 49 | 49 | utils.Sugar.Debugf("Start AccountServer listening on %d", conf.GlobalConf.AccountConf.Port) |
| 50 | 50 | |
| 51 | - return gs.Serve(lis) | |
| 51 | + return s.GrpcServer.Serve(lis) | |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | func (s *AccountServer)Stop() { |
| 55 | - s.BasicServer.Close() | |
| 55 | + s.BasicServer.Stop() | |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | type GameServer struct{ |
| ... | ... | @@ -83,17 +83,17 @@ func (s *GameServer)Start() error { |
| 83 | 83 | models.InitGameServerModels() |
| 84 | 84 | |
| 85 | 85 | //new一个grpc |
| 86 | - gs := grpc.NewServer(grpc.UnaryInterceptor(GameServerInterceptor)) | |
| 86 | + s.GrpcServer = grpc.NewServer(grpc.UnaryInterceptor(GameServerInterceptor)) | |
| 87 | 87 | |
| 88 | - pb.RegisterGameServer(gs, s) | |
| 89 | - reflection.Register(gs) //在给定的gRPC服务器上注册服务器反射服务 | |
| 88 | + pb.RegisterGameServer(s.GrpcServer, s) | |
| 89 | + reflection.Register(s.GrpcServer) //在给定的gRPC服务器上注册服务器反射服务 | |
| 90 | 90 | |
| 91 | 91 | // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。 |
| 92 | 92 | // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。 |
| 93 | 93 | utils.Sugar.Debugf("Start GameServer listening on %d", conf.GlobalConf.GameConf.Port) |
| 94 | - return gs.Serve(lis) | |
| 94 | + return s.GrpcServer.Serve(lis) | |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | 97 | func (s *GameServer)Stop() { |
| 98 | - s.BasicServer.Close() | |
| 98 | + s.BasicServer.Stop() | |
| 99 | 99 | } |
| 100 | 100 | \ No newline at end of file | ... | ... |
cmd/account.go
| 1 | 1 | package main |
| 2 | 2 | |
| 3 | 3 | import ( |
| 4 | + "os" | |
| 5 | + "os/signal" | |
| 4 | 6 | "pro2d/actions" |
| 5 | 7 | "pro2d/utils" |
| 8 | + "syscall" | |
| 6 | 9 | ) |
| 7 | 10 | |
| 8 | 11 | func main() { |
| 9 | 12 | err := make(chan error) |
| 13 | + stopChan := make(chan os.Signal) | |
| 14 | + signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) | |
| 15 | + | |
| 10 | 16 | server := actions.NewAccountServer() |
| 11 | 17 | go func() { |
| 12 | - defer server.Stop() | |
| 13 | 18 | err <- server.Start() |
| 14 | 19 | }() |
| 15 | 20 | |
| 16 | - utils.Sugar.Errorf("server error: %v", <- err) | |
| 21 | + | |
| 22 | + select { | |
| 23 | + case e := <- err: | |
| 24 | + utils.Sugar.Errorf("game server error: %v", e) | |
| 25 | + case <-stopChan: | |
| 26 | + // 平滑关闭服务 | |
| 27 | + server.Stop() | |
| 28 | + } | |
| 17 | 29 | } | ... | ... |
cmd/game.go
| 1 | 1 | package main |
| 2 | 2 | |
| 3 | 3 | import ( |
| 4 | + "os" | |
| 5 | + "os/signal" | |
| 4 | 6 | "pro2d/actions" |
| 5 | 7 | "pro2d/utils" |
| 8 | + "syscall" | |
| 6 | 9 | ) |
| 7 | 10 | |
| 8 | 11 | func main() { |
| 9 | 12 | err := make(chan error) |
| 10 | - | |
| 13 | + stopChan := make(chan os.Signal) | |
| 14 | + signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) | |
| 11 | 15 | |
| 12 | 16 | server := actions.NewGameServer() |
| 13 | 17 | go func() { |
| 14 | - defer server.Stop() | |
| 15 | 18 | err <- server.Start() |
| 16 | 19 | }() |
| 17 | 20 | |
| 18 | - utils.Sugar.Errorf("server error: %v", <- err) | |
| 21 | + | |
| 22 | + select { | |
| 23 | + case e := <- err: | |
| 24 | + utils.Sugar.Errorf("game server error: %v", e) | |
| 25 | + case <-stopChan: | |
| 26 | + // 平滑关闭服务 | |
| 27 | + server.Stop() | |
| 28 | + } | |
| 19 | 29 | } | ... | ... |
components/db/mongo.go
| ... | ... | @@ -9,7 +9,6 @@ import ( |
| 9 | 9 | "go.mongodb.org/mongo-driver/mongo/readpref" |
| 10 | 10 | "go.mongodb.org/mongo-driver/x/bsonx" |
| 11 | 11 | "pro2d/utils" |
| 12 | - "reflect" | |
| 13 | 12 | "sort" |
| 14 | 13 | "strconv" |
| 15 | 14 | "time" |
| ... | ... | @@ -96,8 +95,7 @@ func NewMongoColl(key string, schema interface{}) *MgoColl { |
| 96 | 95 | } |
| 97 | 96 | |
| 98 | 97 | func FindOne(pri interface{}, schema interface{}) error { |
| 99 | - s := reflect.TypeOf(schema) | |
| 100 | - r := MongoDatabase.Collection(s.Name()).FindOne(context.TODO(), pri) | |
| 98 | + r := MongoDatabase.Collection(utils.GetCollName(schema)).FindOne(context.TODO(), pri) | |
| 101 | 99 | return r.Decode(schema) |
| 102 | 100 | } |
| 103 | 101 | ... | ... |
components/etcd/etcd.go
| ... | ... | @@ -17,6 +17,7 @@ func NewEtcdClient(conf *conf.Etcd) *EtcdClient { |
| 17 | 17 | cli, err := clientv3.New(clientv3.Config{ |
| 18 | 18 | Endpoints: conf.Endpoints, |
| 19 | 19 | DialTimeout: time.Duration(conf.DialTimeout) * time.Second, |
| 20 | + Logger: utils.Logger, | |
| 20 | 21 | }) |
| 21 | 22 | if err != nil { |
| 22 | 23 | utils.Sugar.Errorf("etcd init err: %v", err) |
| ... | ... | @@ -49,25 +50,25 @@ func (e *EtcdClient)PutWithLeasePrefix(prefix, key, val string, ttl int64) error |
| 49 | 50 | return err |
| 50 | 51 | } |
| 51 | 52 | |
| 52 | - _, err = lease.KeepAlive(context.TODO(), leaseResp.ID) | |
| 53 | + keepRespChan, err := lease.KeepAlive(context.TODO(), leaseResp.ID) | |
| 53 | 54 | if err != nil { |
| 54 | 55 | utils.Sugar.Errorf("keepalive err: %v", err) |
| 55 | 56 | return err |
| 56 | 57 | } |
| 57 | - //go func() { | |
| 58 | - // for { | |
| 59 | - // select { | |
| 60 | - // case keepResp := <-keepRespChan: | |
| 61 | - // if keepRespChan == nil { | |
| 62 | - // fmt.Println("租约已经失效") | |
| 63 | - // goto END | |
| 64 | - // } else { //每秒会续租一次,所以就会受到一次应答 | |
| 65 | - // fmt.Println("收到自动续租应答:", keepResp.ID) | |
| 66 | - // } | |
| 67 | - // } | |
| 68 | - // } | |
| 69 | - // END: | |
| 70 | - //}() | |
| 58 | + go func() { | |
| 59 | + for { | |
| 60 | + select { | |
| 61 | + case _ = <-keepRespChan: | |
| 62 | + if keepRespChan == nil { | |
| 63 | + fmt.Println("租约已经失效") | |
| 64 | + goto END | |
| 65 | + } else { //每秒会续租一次,所以就会受到一次应答 | |
| 66 | + //fmt.Println("收到自动续租应答:", keepResp.ID) | |
| 67 | + } | |
| 68 | + } | |
| 69 | + } | |
| 70 | + END: | |
| 71 | + }() | |
| 71 | 72 | return nil |
| 72 | 73 | } |
| 73 | 74 | |
| ... | ... | @@ -99,4 +100,8 @@ func (e *EtcdClient)GetByPrefix(prefix string) map[string]string { |
| 99 | 100 | m[string(v.Key)] = string(v.Value) |
| 100 | 101 | } |
| 101 | 102 | return m |
| 103 | +} | |
| 104 | + | |
| 105 | +func (e *EtcdClient)Close() { | |
| 106 | + e.etcd.Close() | |
| 102 | 107 | } |
| 103 | 108 | \ No newline at end of file | ... | ... |
models/role.go
| ... | ... | @@ -22,9 +22,11 @@ func RoleExistByUid(uid string) (bool, *RoleModel){ |
| 22 | 22 | if err := db.FindOne(db.GetBsonM("uid", uid), data); err != nil { |
| 23 | 23 | return false, nil |
| 24 | 24 | } |
| 25 | - m := NewRole(data.Id) | |
| 26 | - m.Load() | |
| 27 | - return true, m | |
| 25 | + | |
| 26 | + return true, &RoleModel{ | |
| 27 | + MgoColl: db.NewMongoColl(strconv.Itoa(int(data.Id)), data), | |
| 28 | + Role: data, | |
| 29 | + } | |
| 28 | 30 | } |
| 29 | 31 | |
| 30 | 32 | func NewRole(id int64) *RoleModel { | ... | ... |
test/client.go
| ... | ... | @@ -35,6 +35,7 @@ func Login(loginUri, token string) { |
| 35 | 35 | defer gameConn.Close() |
| 36 | 36 | |
| 37 | 37 | client:= pb.NewGameClient(gameConn) |
| 38 | + var role *pb.Role | |
| 38 | 39 | loginRsp, err := client.LoginHandler(context.Background(), &pb.Token{ |
| 39 | 40 | Token: token, |
| 40 | 41 | }) |
| ... | ... | @@ -43,17 +44,20 @@ func Login(loginUri, token string) { |
| 43 | 44 | utils.Sugar.Errorf("login error: %v", err) |
| 44 | 45 | return |
| 45 | 46 | } |
| 47 | + role = loginRsp.Role | |
| 46 | 48 | |
| 47 | - print(loginRsp) | |
| 48 | - | |
| 49 | - createRole, err := client.CreateRoleHandler(context.Background(), &pb.Token{Token: token}) | |
| 50 | - if err != nil { | |
| 51 | - utils.Sugar.Errorf("create role err: %v", err) | |
| 52 | - return | |
| 49 | + if loginRsp.Rsp.Code != 0 { | |
| 50 | + utils.Sugar.Debugf("login rsp: %v", loginRsp.Rsp.Msg) | |
| 51 | + createRole, err := client.CreateRoleHandler(context.Background(), &pb.Token{Token: token}) | |
| 52 | + if err != nil { | |
| 53 | + utils.Sugar.Errorf("create role err: %v", err) | |
| 54 | + return | |
| 55 | + } | |
| 56 | + utils.Sugar.Debug("create role rsp: ", createRole.Rsp.Code, createRole.Rsp.Msg) | |
| 57 | + role = createRole.Role | |
| 53 | 58 | } |
| 54 | - print(createRole) | |
| 55 | 59 | |
| 56 | - utils.Sugar.Debug("login rsp: ", createRole.Rsp.Code, createRole.Rsp.Msg) | |
| 60 | + utils.Sugar.Debugf("login successful role: %v", role) | |
| 57 | 61 | } |
| 58 | 62 | |
| 59 | 63 | func main() { |
| ... | ... | @@ -64,11 +68,11 @@ func main() { |
| 64 | 68 | } |
| 65 | 69 | defer conn.Close() |
| 66 | 70 | c := pb.NewAccountClient(conn) |
| 67 | - err = Register(c,"17683852936", "123456") | |
| 68 | - if err != nil { | |
| 69 | - utils.Sugar.Errorf("register err: %v", err) | |
| 70 | - return | |
| 71 | - } | |
| 71 | + //err = Register(c,"17683852936", "123456") | |
| 72 | + //if err != nil { | |
| 73 | + // utils.Sugar.Errorf("register err: %v", err) | |
| 74 | + // return | |
| 75 | + //} | |
| 72 | 76 | rsp, err := c.CreateTokenHandler(context.Background(), &pb.AccountInfo{ |
| 73 | 77 | Phone: "17683852936", |
| 74 | 78 | Password: "123456", |
| ... | ... | @@ -84,7 +88,7 @@ func main() { |
| 84 | 88 | return |
| 85 | 89 | } |
| 86 | 90 | |
| 87 | - Login(rsp.GameService.Address, rsp.Token) | |
| 88 | - | |
| 89 | - | |
| 91 | + if len(rsp.GameService) >0 { | |
| 92 | + Login(rsp.GameService[0].Address, rsp.Token) | |
| 93 | + } | |
| 90 | 94 | } | ... | ... |
utils/utils.go
| ... | ... | @@ -5,20 +5,21 @@ import ( |
| 5 | 5 | "strings" |
| 6 | 6 | ) |
| 7 | 7 | |
| 8 | -func GetCollName(schema interface{}) string { | |
| 8 | +func GetSchemaType(schema interface{}) reflect.Type { | |
| 9 | 9 | s := reflect.TypeOf(schema) |
| 10 | 10 | if s.Kind() == reflect.Ptr { |
| 11 | 11 | s = reflect.TypeOf(schema).Elem() |
| 12 | 12 | } |
| 13 | + return s | |
| 14 | +} | |
| 13 | 15 | |
| 14 | - return strings.ToLower(s.Name()) | |
| 16 | +func GetCollName(schema interface{}) string { | |
| 17 | + return strings.ToLower(GetSchemaType(schema).Name()) | |
| 15 | 18 | } |
| 16 | 19 | |
| 17 | 20 | func GetPriKey(schema interface{}) string { |
| 18 | - s := reflect.TypeOf(schema) | |
| 19 | - if s.Kind() == reflect.Ptr { | |
| 20 | - s = reflect.TypeOf(schema).Elem() | |
| 21 | - } | |
| 21 | + s := GetSchemaType(schema) | |
| 22 | + | |
| 22 | 23 | var pri string |
| 23 | 24 | for i := 0; i < s.NumField(); i++ { |
| 24 | 25 | if s.Field(i).Tag.Get("pri") == "1" { |
| ... | ... | @@ -30,10 +31,7 @@ func GetPriKey(schema interface{}) string { |
| 30 | 31 | } |
| 31 | 32 | |
| 32 | 33 | func FindIndex(schema interface{}) (string, []string){ |
| 33 | - s := reflect.TypeOf(schema) | |
| 34 | - if s.Kind() == reflect.Ptr { | |
| 35 | - s = reflect.TypeOf(schema).Elem() | |
| 36 | - } | |
| 34 | + s := GetSchemaType(schema) | |
| 37 | 35 | |
| 38 | 36 | var index []string |
| 39 | 37 | for i := 0; i < s.NumField(); i++ { | ... | ... |