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++ { | ... | ... |