Commit f7f4beb57da45b63409ea05d6808967001a10fa6

Authored by zhangqijia
1 parent 286f6dbe

新增grpc平滑关闭,修复createrole的bug, 新增的函数

@@ -32,8 +32,4 @@ $ make run @@ -32,8 +32,4 @@ $ make run
32 测试 32 测试
33 ```shell 33 ```shell
34 $ make test 34 $ make test
35 -```  
36 -  
37 -  
38 -  
39 - 35 +```
40 \ No newline at end of file 36 \ No newline at end of file
actions/accountaction.go
@@ -60,7 +60,7 @@ func (s *AccountServer) CreateTokenHandler(ctx context.Context, in *pb.AccountIn @@ -60,7 +60,7 @@ func (s *AccountServer) CreateTokenHandler(ctx context.Context, in *pb.AccountIn
60 Rsp: &pb.PubRsp{ 60 Rsp: &pb.PubRsp{
61 Code: 0, 61 Code: 0,
62 }, 62 },
63 - Token: utils.CreateToken(in), 63 + Token: utils.CreateToken(m.AccountInfo),
64 GameService: gameInfo, 64 GameService: gameInfo,
65 }, nil 65 }, nil
66 } 66 }
@@ -2,15 +2,18 @@ package actions @@ -2,15 +2,18 @@ package actions
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
  5 + "google.golang.org/grpc"
5 "net" 6 "net"
6 "pro2d/components/db" 7 "pro2d/components/db"
7 "pro2d/components/etcd" 8 "pro2d/components/etcd"
8 "pro2d/conf" 9 "pro2d/conf"
  10 + "pro2d/utils"
9 ) 11 )
10 12
11 type BasicServer struct { 13 type BasicServer struct {
12 - SConf *conf.SConf 14 + SConf *conf.SConf
13 EtcdClient *etcd.EtcdClient 15 EtcdClient *etcd.EtcdClient
  16 + GrpcServer *grpc.Server
14 } 17 }
15 18
16 func NewServer() *BasicServer { 19 func NewServer() *BasicServer {
@@ -34,5 +37,8 @@ func (b *BasicServer) Start(sConf *conf.SConf) (net.Listener, error) { @@ -34,5 +37,8 @@ func (b *BasicServer) Start(sConf *conf.SConf) (net.Listener, error) {
34 return lis, err 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,6 +5,7 @@ import (
5 "errors" 5 "errors"
6 "fmt" 6 "fmt"
7 "google.golang.org/grpc/metadata" 7 "google.golang.org/grpc/metadata"
  8 + "pro2d/conf"
8 "pro2d/models" 9 "pro2d/models"
9 "pro2d/protos/pb" 10 "pro2d/protos/pb"
10 "pro2d/utils" 11 "pro2d/utils"
@@ -45,11 +46,9 @@ func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.Token) (*pb.R @@ -45,11 +46,9 @@ func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.Token) (*pb.R
45 } 46 }
46 ok, role := models.RoleExistByUid(account.Uid) 47 ok, role := models.RoleExistByUid(account.Uid)
47 if !ok { 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 role.Create() 52 role.Create()
54 53
55 } 54 }
@@ -67,6 +66,7 @@ func (s *GameServer) LoginHandler(ctx context.Context, in *pb.Token) (*pb.RoleRs @@ -67,6 +66,7 @@ func (s *GameServer) LoginHandler(ctx context.Context, in *pb.Token) (*pb.RoleRs
67 if account == nil { 66 if account == nil {
68 return nil, fmt.Errorf("token is error") 67 return nil, fmt.Errorf("token is error")
69 } 68 }
  69 + utils.Sugar.Debugf("login account: %v", account)
70 ok, role := models.RoleExistByUid(account.Uid) 70 ok, role := models.RoleExistByUid(account.Uid)
71 if !ok { 71 if !ok {
72 return &pb.RoleRsp{ 72 return &pb.RoleRsp{
@@ -39,20 +39,20 @@ func (s *AccountServer)Start() error { @@ -39,20 +39,20 @@ func (s *AccountServer)Start() error {
39 models.InitAccountServerModels() 39 models.InitAccountServerModels()
40 40
41 //new一个grpc 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 // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。 47 // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。
48 // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。 48 // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。
49 utils.Sugar.Debugf("Start AccountServer listening on %d", conf.GlobalConf.AccountConf.Port) 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 func (s *AccountServer)Stop() { 54 func (s *AccountServer)Stop() {
55 - s.BasicServer.Close() 55 + s.BasicServer.Stop()
56 } 56 }
57 57
58 type GameServer struct{ 58 type GameServer struct{
@@ -83,17 +83,17 @@ func (s *GameServer)Start() error { @@ -83,17 +83,17 @@ func (s *GameServer)Start() error {
83 models.InitGameServerModels() 83 models.InitGameServerModels()
84 84
85 //new一个grpc 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 // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。 91 // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。
92 // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。 92 // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。
93 utils.Sugar.Debugf("Start GameServer listening on %d", conf.GlobalConf.GameConf.Port) 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 func (s *GameServer)Stop() { 97 func (s *GameServer)Stop() {
98 - s.BasicServer.Close() 98 + s.BasicServer.Stop()
99 } 99 }
100 \ No newline at end of file 100 \ No newline at end of file
1 package main 1 package main
2 2
3 import ( 3 import (
  4 + "os"
  5 + "os/signal"
4 "pro2d/actions" 6 "pro2d/actions"
5 "pro2d/utils" 7 "pro2d/utils"
  8 + "syscall"
6 ) 9 )
7 10
8 func main() { 11 func main() {
9 err := make(chan error) 12 err := make(chan error)
  13 + stopChan := make(chan os.Signal)
  14 + signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)
  15 +
10 server := actions.NewAccountServer() 16 server := actions.NewAccountServer()
11 go func() { 17 go func() {
12 - defer server.Stop()  
13 err <- server.Start() 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 }
1 package main 1 package main
2 2
3 import ( 3 import (
  4 + "os"
  5 + "os/signal"
4 "pro2d/actions" 6 "pro2d/actions"
5 "pro2d/utils" 7 "pro2d/utils"
  8 + "syscall"
6 ) 9 )
7 10
8 func main() { 11 func main() {
9 err := make(chan error) 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 server := actions.NewGameServer() 16 server := actions.NewGameServer()
13 go func() { 17 go func() {
14 - defer server.Stop()  
15 err <- server.Start() 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,7 +9,6 @@ import (
9 "go.mongodb.org/mongo-driver/mongo/readpref" 9 "go.mongodb.org/mongo-driver/mongo/readpref"
10 "go.mongodb.org/mongo-driver/x/bsonx" 10 "go.mongodb.org/mongo-driver/x/bsonx"
11 "pro2d/utils" 11 "pro2d/utils"
12 - "reflect"  
13 "sort" 12 "sort"
14 "strconv" 13 "strconv"
15 "time" 14 "time"
@@ -96,8 +95,7 @@ func NewMongoColl(key string, schema interface{}) *MgoColl { @@ -96,8 +95,7 @@ func NewMongoColl(key string, schema interface{}) *MgoColl {
96 } 95 }
97 96
98 func FindOne(pri interface{}, schema interface{}) error { 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 return r.Decode(schema) 99 return r.Decode(schema)
102 } 100 }
103 101
components/etcd/etcd.go
@@ -17,6 +17,7 @@ func NewEtcdClient(conf *conf.Etcd) *EtcdClient { @@ -17,6 +17,7 @@ func NewEtcdClient(conf *conf.Etcd) *EtcdClient {
17 cli, err := clientv3.New(clientv3.Config{ 17 cli, err := clientv3.New(clientv3.Config{
18 Endpoints: conf.Endpoints, 18 Endpoints: conf.Endpoints,
19 DialTimeout: time.Duration(conf.DialTimeout) * time.Second, 19 DialTimeout: time.Duration(conf.DialTimeout) * time.Second,
  20 + Logger: utils.Logger,
20 }) 21 })
21 if err != nil { 22 if err != nil {
22 utils.Sugar.Errorf("etcd init err: %v", err) 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,25 +50,25 @@ func (e *EtcdClient)PutWithLeasePrefix(prefix, key, val string, ttl int64) error
49 return err 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 if err != nil { 54 if err != nil {
54 utils.Sugar.Errorf("keepalive err: %v", err) 55 utils.Sugar.Errorf("keepalive err: %v", err)
55 return err 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 return nil 72 return nil
72 } 73 }
73 74
@@ -99,4 +100,8 @@ func (e *EtcdClient)GetByPrefix(prefix string) map[string]string { @@ -99,4 +100,8 @@ func (e *EtcdClient)GetByPrefix(prefix string) map[string]string {
99 m[string(v.Key)] = string(v.Value) 100 m[string(v.Key)] = string(v.Value)
100 } 101 }
101 return m 102 return m
  103 +}
  104 +
  105 +func (e *EtcdClient)Close() {
  106 + e.etcd.Close()
102 } 107 }
103 \ No newline at end of file 108 \ No newline at end of file
@@ -22,9 +22,11 @@ func RoleExistByUid(uid string) (bool, *RoleModel){ @@ -22,9 +22,11 @@ func RoleExistByUid(uid string) (bool, *RoleModel){
22 if err := db.FindOne(db.GetBsonM("uid", uid), data); err != nil { 22 if err := db.FindOne(db.GetBsonM("uid", uid), data); err != nil {
23 return false, nil 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 func NewRole(id int64) *RoleModel { 32 func NewRole(id int64) *RoleModel {
1 -Subproject commit 3df1fd713f54812f465bbc704c6677aec3ccbe92 1 +Subproject commit a01eb6ede9a8e3f9d5ec30bf41e9f6e0f4f9ee1f
@@ -35,6 +35,7 @@ func Login(loginUri, token string) { @@ -35,6 +35,7 @@ func Login(loginUri, token string) {
35 defer gameConn.Close() 35 defer gameConn.Close()
36 36
37 client:= pb.NewGameClient(gameConn) 37 client:= pb.NewGameClient(gameConn)
  38 + var role *pb.Role
38 loginRsp, err := client.LoginHandler(context.Background(), &pb.Token{ 39 loginRsp, err := client.LoginHandler(context.Background(), &pb.Token{
39 Token: token, 40 Token: token,
40 }) 41 })
@@ -43,17 +44,20 @@ func Login(loginUri, token string) { @@ -43,17 +44,20 @@ func Login(loginUri, token string) {
43 utils.Sugar.Errorf("login error: %v", err) 44 utils.Sugar.Errorf("login error: %v", err)
44 return 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 func main() { 63 func main() {
@@ -64,11 +68,11 @@ func main() { @@ -64,11 +68,11 @@ func main() {
64 } 68 }
65 defer conn.Close() 69 defer conn.Close()
66 c := pb.NewAccountClient(conn) 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 rsp, err := c.CreateTokenHandler(context.Background(), &pb.AccountInfo{ 76 rsp, err := c.CreateTokenHandler(context.Background(), &pb.AccountInfo{
73 Phone: "17683852936", 77 Phone: "17683852936",
74 Password: "123456", 78 Password: "123456",
@@ -84,7 +88,7 @@ func main() { @@ -84,7 +88,7 @@ func main() {
84 return 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 }
@@ -5,20 +5,21 @@ import ( @@ -5,20 +5,21 @@ import (
5 "strings" 5 "strings"
6 ) 6 )
7 7
8 -func GetCollName(schema interface{}) string { 8 +func GetSchemaType(schema interface{}) reflect.Type {
9 s := reflect.TypeOf(schema) 9 s := reflect.TypeOf(schema)
10 if s.Kind() == reflect.Ptr { 10 if s.Kind() == reflect.Ptr {
11 s = reflect.TypeOf(schema).Elem() 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 func GetPriKey(schema interface{}) string { 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 var pri string 23 var pri string
23 for i := 0; i < s.NumField(); i++ { 24 for i := 0; i < s.NumField(); i++ {
24 if s.Field(i).Tag.Get("pri") == "1" { 25 if s.Field(i).Tag.Get("pri") == "1" {
@@ -30,10 +31,7 @@ func GetPriKey(schema interface{}) string { @@ -30,10 +31,7 @@ func GetPriKey(schema interface{}) string {
30 } 31 }
31 32
32 func FindIndex(schema interface{}) (string, []string){ 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 var index []string 36 var index []string
39 for i := 0; i < s.NumField(); i++ { 37 for i := 0; i < s.NumField(); i++ {