Commit 765431a462c47308a5fc53e377699afdacc51c2b
1 parent
77f5eec7
增加schema接口, 抽象 models + db
Showing
38 changed files
with
683 additions
and
632 deletions
Show diff stats
cmd/gameserver/agent.go
@@ -5,9 +5,9 @@ import ( | @@ -5,9 +5,9 @@ import ( | ||
5 | "math" | 5 | "math" |
6 | "pro2d/common" | 6 | "pro2d/common" |
7 | "pro2d/common/components" | 7 | "pro2d/common/components" |
8 | + "pro2d/common/logger" | ||
8 | "pro2d/models" | 9 | "pro2d/models" |
9 | "pro2d/utils" | 10 | "pro2d/utils" |
10 | - "pro2d/utils/logger" | ||
11 | "sync/atomic" | 11 | "sync/atomic" |
12 | ) | 12 | ) |
13 | 13 | ||
@@ -43,7 +43,7 @@ func (c *Agent) OnConnection(conn components.IConnection) { | @@ -43,7 +43,7 @@ func (c *Agent) OnConnection(conn components.IConnection) { | ||
43 | 43 | ||
44 | func (c *Agent) OnMessage(msg components.IMessage) { | 44 | func (c *Agent) OnMessage(msg components.IMessage) { |
45 | atomic.StoreInt64(&c.lastHeartCheckTime, utils.Timex()) | 45 | atomic.StoreInt64(&c.lastHeartCheckTime, utils.Timex()) |
46 | - md := c.Server.GetPlugin().GetAction(msg.GetHeader().GetMsgID()) | 46 | + md := c.Server.GetAction(msg.GetHeader().GetMsgID()) |
47 | if md == nil { | 47 | if md == nil { |
48 | logger.Debug("cmd: %d, md is nil", msg.GetHeader().GetMsgID()) | 48 | logger.Debug("cmd: %d, md is nil", msg.GetHeader().GetMsgID()) |
49 | return | 49 | return |
@@ -52,17 +52,17 @@ func (c *Agent) OnMessage(msg components.IMessage) { | @@ -52,17 +52,17 @@ func (c *Agent) OnMessage(msg components.IMessage) { | ||
52 | logger.Debug("protocode handler: %d", msg.GetHeader().GetMsgID()) | 52 | logger.Debug("protocode handler: %d", msg.GetHeader().GetMsgID()) |
53 | //fmt.Printf("errCode: %d, protomsg:%v\n", errCode, protomsg) | 53 | //fmt.Printf("errCode: %d, protomsg:%v\n", errCode, protomsg) |
54 | 54 | ||
55 | - f := md.(func (conn components.IConnection, msg components.IMessage) (int32, interface{})) | ||
56 | - errCode, protomsg := f(c, msg) | 55 | + f := md.(func (msg components.IMessage) (int32, interface{})) |
56 | + errCode, protomsg := f(msg) | ||
57 | rsp, err := proto.Marshal(protomsg.(proto.Message)) | 57 | rsp, err := proto.Marshal(protomsg.(proto.Message)) |
58 | if err != nil { | 58 | if err != nil { |
59 | - conn := c.Server.GetIConnection(msg.GetSessId()) | 59 | + conn := msg.GetSession() |
60 | if conn != nil { | 60 | if conn != nil { |
61 | conn.Send(-100, msg.GetHeader().GetMsgID(), nil) | 61 | conn.Send(-100, msg.GetHeader().GetMsgID(), nil) |
62 | } | 62 | } |
63 | return | 63 | return |
64 | } | 64 | } |
65 | - conn := c.Server.GetIConnection(msg.GetSessId()) | 65 | + conn := msg.GetSession() |
66 | if conn != nil { | 66 | if conn != nil { |
67 | conn.Send(errCode, msg.GetHeader().GetMsgID(), rsp) | 67 | conn.Send(errCode, msg.GetHeader().GetMsgID(), rsp) |
68 | } | 68 | } |
cmd/gameserver/game.go
1 | package main | 1 | package main |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | - "context" | ||
5 | "fmt" | 4 | "fmt" |
6 | - "net/http" | ||
7 | _ "net/http/pprof" | 5 | _ "net/http/pprof" |
8 | - "os" | ||
9 | - "os/signal" | 6 | + "pro2d/common" |
10 | "pro2d/common/components" | 7 | "pro2d/common/components" |
11 | - "pro2d/conf" | 8 | + "pro2d/common/db" |
12 | "pro2d/models" | 9 | "pro2d/models" |
13 | - //_ "pro2d/cmd/gameserver/plugin" | ||
14 | - "pro2d/utils/db" | ||
15 | - "pro2d/utils/etcd" | ||
16 | - "pro2d/utils/logger" | 10 | + |
11 | + "pro2d/common/etcd" | ||
17 | "sync" | 12 | "sync" |
18 | - "syscall" | ||
19 | ) | 13 | ) |
20 | 14 | ||
21 | type GameServer struct { | 15 | type GameServer struct { |
@@ -25,12 +19,12 @@ type GameServer struct { | @@ -25,12 +19,12 @@ type GameServer struct { | ||
25 | Agents *sync.Map | 19 | Agents *sync.Map |
26 | } | 20 | } |
27 | 21 | ||
28 | -func NewGameServer(sconf *conf.SConf) (*GameServer, error) { | 22 | +func NewGameServer(sconf *common.SConf) (*GameServer, error) { |
29 | s := &GameServer{ | 23 | s := &GameServer{ |
30 | Agents: new(sync.Map), | 24 | Agents: new(sync.Map), |
31 | } | 25 | } |
32 | 26 | ||
33 | - options := []components.Option{ | 27 | + options := []components.ServerOption{ |
34 | components.WithPlugin(components.NewPlugin(sconf.PluginPath)), | 28 | components.WithPlugin(components.NewPlugin(sconf.PluginPath)), |
35 | components.WithSplitter(components.NewPBSplitter()), | 29 | components.WithSplitter(components.NewPBSplitter()), |
36 | components.WithConnCbk(s.OnConnection), | 30 | components.WithConnCbk(s.OnConnection), |
@@ -42,21 +36,34 @@ func NewGameServer(sconf *conf.SConf) (*GameServer, error) { | @@ -42,21 +36,34 @@ func NewGameServer(sconf *conf.SConf) (*GameServer, error) { | ||
42 | iserver := components.NewServer(sconf.Port, options...) | 36 | iserver := components.NewServer(sconf.Port, options...) |
43 | s.IServer = iserver | 37 | s.IServer = iserver |
44 | 38 | ||
45 | - //mongo 初始化 | ||
46 | - db.MongoDatabase = db.MongoClient.Database(sconf.DBName) | ||
47 | - models.InitGameServerModels() | 39 | + //mgo init |
40 | + err := db.ConnectMongo(sconf.MongoConf) | ||
41 | + if err != nil { | ||
42 | + return nil, err | ||
43 | + } | ||
44 | + models.InitModels() | ||
48 | 45 | ||
49 | //Etcd 初始化 | 46 | //Etcd 初始化 |
50 | - var err error | ||
51 | - s.EtcdClient, err = etcd.NewEtcdClient(conf.GlobalConf.Etcd) | 47 | + s.EtcdClient, err = etcd.NewEtcdClient(common.GlobalConf.Etcd) |
52 | if err != nil { | 48 | if err != nil { |
53 | return nil, err | 49 | return nil, err |
54 | } | 50 | } |
55 | - s.EtcdClient.PutWithLeasePrefix(conf.GlobalConf.GameConf.Name, conf.GlobalConf.GameConf.ID, fmt.Sprintf("%s:%d", conf.GlobalConf.GameConf.IP, conf.GlobalConf.GameConf.Port), 5) | 51 | + s.EtcdClient.PutWithLeasePrefix(common.GlobalConf.GameConf.Name, common.GlobalConf.GameConf.ID, fmt.Sprintf("%s:%d", common.GlobalConf.GameConf.IP, common.GlobalConf.GameConf.Port), 5) |
56 | 52 | ||
57 | return s, nil | 53 | return s, nil |
58 | } | 54 | } |
59 | 55 | ||
56 | +func (s *GameServer) Start() error { | ||
57 | + return s.IServer.Start() | ||
58 | +} | ||
59 | + | ||
60 | +func (s *GameServer) Stop() { | ||
61 | + s.IServer.Stop() | ||
62 | + | ||
63 | + db.CloseMongo() | ||
64 | + s.EtcdClient.Close() | ||
65 | +} | ||
66 | + | ||
60 | func (s *GameServer) OnConnection(conn components.IConnection) { | 67 | func (s *GameServer) OnConnection(conn components.IConnection) { |
61 | agent := NewAgent(s) | 68 | agent := NewAgent(s) |
62 | agent.OnConnection(conn) | 69 | agent.OnConnection(conn) |
@@ -64,7 +71,7 @@ func (s *GameServer) OnConnection(conn components.IConnection) { | @@ -64,7 +71,7 @@ func (s *GameServer) OnConnection(conn components.IConnection) { | ||
64 | } | 71 | } |
65 | 72 | ||
66 | func (s *GameServer) OnMessage(msg components.IMessage) { | 73 | func (s *GameServer) OnMessage(msg components.IMessage) { |
67 | - agent, ok := s.Agents.Load(msg.GetSessId()) | 74 | + agent, ok := s.Agents.Load(msg.GetSession().GetID()) |
68 | if !ok { | 75 | if !ok { |
69 | return | 76 | return |
70 | } | 77 | } |
@@ -87,50 +94,3 @@ func (s *GameServer) OnClose(conn components.IConnection) { | @@ -87,50 +94,3 @@ func (s *GameServer) OnClose(conn components.IConnection) { | ||
87 | agent.(*Agent).OnClose() | 94 | agent.(*Agent).OnClose() |
88 | s.Agents.Delete(conn.GetID()) | 95 | s.Agents.Delete(conn.GetID()) |
89 | } | 96 | } |
90 | - | ||
91 | -func (s *GameServer) Stop() { | ||
92 | - s.IServer.Stop() | ||
93 | - | ||
94 | - db.MongoClient.Disconnect(context.TODO()) | ||
95 | -} | ||
96 | - | ||
97 | - | ||
98 | -func main() { | ||
99 | - err := make(chan error) | ||
100 | - stopChan := make(chan os.Signal) | ||
101 | - signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) | ||
102 | - | ||
103 | - userChan := make(chan os.Signal) | ||
104 | - signal.Notify(userChan, syscall.SIGUSR1, syscall.SIGUSR2) | ||
105 | - | ||
106 | - s,err1 := NewGameServer(conf.GlobalConf.GameConf) | ||
107 | - if err1 != nil { | ||
108 | - fmt.Errorf(err1.Error()) | ||
109 | - return | ||
110 | - } | ||
111 | - go func() { | ||
112 | - err <- http.ListenAndServe("localhost:6061", nil) | ||
113 | - }() | ||
114 | - | ||
115 | - go func() { | ||
116 | - err <- s.Start() | ||
117 | - }() | ||
118 | - | ||
119 | - for { | ||
120 | - select { | ||
121 | - case e := <- err: | ||
122 | - logger.Error("game server error: %v", e) | ||
123 | - return | ||
124 | - case <-stopChan: | ||
125 | - s.Stop() | ||
126 | - logger.Debug("game stop...") | ||
127 | - return | ||
128 | - case u := <-userChan: | ||
129 | - logger.Debug("userChan .. %v",u.String()) | ||
130 | - e := s.IServer.GetPlugin().LoadPlugin() | ||
131 | - if e != nil { | ||
132 | - logger.Error("err: ", e.Error()) | ||
133 | - } | ||
134 | - } | ||
135 | - } | ||
136 | -} |
@@ -0,0 +1,51 @@ | @@ -0,0 +1,51 @@ | ||
1 | +package main | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "net/http" | ||
6 | + "os" | ||
7 | + "os/signal" | ||
8 | + "pro2d/common" | ||
9 | + "pro2d/common/logger" | ||
10 | + "syscall" | ||
11 | +) | ||
12 | + | ||
13 | +func main() { | ||
14 | + err := make(chan error) | ||
15 | + stopChan := make(chan os.Signal) | ||
16 | + signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) | ||
17 | + | ||
18 | + userChan := make(chan os.Signal) | ||
19 | + signal.Notify(userChan, syscall.SIGUSR1, syscall.SIGUSR2) | ||
20 | + | ||
21 | + s,err1 := NewGameServer(common.GlobalConf.GameConf) | ||
22 | + if err1 != nil { | ||
23 | + fmt.Errorf(err1.Error()) | ||
24 | + return | ||
25 | + } | ||
26 | + go func() { | ||
27 | + err <- http.ListenAndServe(fmt.Sprintf("localhost:%d", common.GlobalConf.GameConf.DebugPort), nil) | ||
28 | + }() | ||
29 | + | ||
30 | + go func() { | ||
31 | + err <- s.Start() | ||
32 | + }() | ||
33 | + | ||
34 | + for { | ||
35 | + select { | ||
36 | + case e := <- err: | ||
37 | + logger.Error("game server error: %v", e) | ||
38 | + return | ||
39 | + case <-stopChan: | ||
40 | + logger.Debug("game stop...") | ||
41 | + s.Stop() | ||
42 | + return | ||
43 | + case u := <-userChan: | ||
44 | + logger.Debug("userChan .. %v",u.String()) | ||
45 | + e := s.IServer.GetPlugin().LoadPlugin() | ||
46 | + if e != nil { | ||
47 | + logger.Error("err: ", e.Error()) | ||
48 | + } | ||
49 | + } | ||
50 | + } | ||
51 | +} |
cmd/gameserver/plugin/RolePlugin.go
@@ -2,11 +2,11 @@ package main | @@ -2,11 +2,11 @@ package main | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "github.com/golang/protobuf/proto" | 4 | "github.com/golang/protobuf/proto" |
5 | + "pro2d/common" | ||
5 | "pro2d/common/components" | 6 | "pro2d/common/components" |
6 | - "pro2d/conf" | 7 | + "pro2d/common/logger" |
7 | "pro2d/models" | 8 | "pro2d/models" |
8 | "pro2d/pb" | 9 | "pro2d/pb" |
9 | - "pro2d/utils/logger" | ||
10 | ) | 10 | ) |
11 | 11 | ||
12 | func HeartRpc(msg components.IMessage) (int32, interface{}) { | 12 | func HeartRpc(msg components.IMessage) (int32, interface{}) { |
@@ -25,7 +25,7 @@ func CreateRpc(msg components.IMessage) (int32, interface{}) { | @@ -25,7 +25,7 @@ func CreateRpc(msg components.IMessage) (int32, interface{}) { | ||
25 | return 2, nil | 25 | return 2, nil |
26 | } | 26 | } |
27 | 27 | ||
28 | - roleId := conf.SnowFlack.NextValStr() | 28 | + roleId := common.SnowFlack.NextValStr() |
29 | role = models.NewRole(roleId) | 29 | role = models.NewRole(roleId) |
30 | if err := role.Create(); err != nil { | 30 | if err := role.Create(); err != nil { |
31 | logger.Error("CreateRpc role create err: %v", err) | 31 | logger.Error("CreateRpc role create err: %v", err) |
cmd/gameserver/plugin/protocode.go
cmd/httpserver/AccountAction.go
@@ -2,7 +2,7 @@ package main | @@ -2,7 +2,7 @@ package main | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "github.com/gin-gonic/gin" | 4 | "github.com/gin-gonic/gin" |
5 | - "pro2d/conf" | 5 | + "pro2d/common" |
6 | "pro2d/models" | 6 | "pro2d/models" |
7 | "pro2d/pb" | 7 | "pro2d/pb" |
8 | "pro2d/utils" | 8 | "pro2d/utils" |
@@ -23,7 +23,7 @@ func (h *AccountAction) Register(c *gin.Context) (int, interface{}){ | @@ -23,7 +23,7 @@ func (h *AccountAction) Register(c *gin.Context) (int, interface{}){ | ||
23 | return -2 , "account exists: " + register.Phone | 23 | return -2 , "account exists: " + register.Phone |
24 | } | 24 | } |
25 | 25 | ||
26 | - account.Uid = conf.SnowFlack.NextValStr() | 26 | + account.Uid = common.SnowFlack.NextValStr() |
27 | account.Password = utils.Md5V(register.Password) | 27 | account.Password = utils.Md5V(register.Password) |
28 | if err := account.Create(); err != nil{ | 28 | if err := account.Create(); err != nil{ |
29 | return -3, "account register err: " + err.Error() | 29 | return -3, "account register err: " + err.Error() |
@@ -47,10 +47,10 @@ func (h *AccountAction) Login(c *gin.Context) (int,interface{}) { | @@ -47,10 +47,10 @@ func (h *AccountAction) Login(c *gin.Context) (int,interface{}) { | ||
47 | } | 47 | } |
48 | 48 | ||
49 | var gs []*pb.ServiceInfo | 49 | var gs []*pb.ServiceInfo |
50 | - for k, v := range h.HttpServer.EtcdClient.GetByPrefix(conf.GlobalConf.GameConf.Name) { | 50 | + for k, v := range h.HttpServer.EtcdClient.GetByPrefix(common.GlobalConf.GameConf.Name) { |
51 | gs = append(gs, &pb.ServiceInfo{ | 51 | gs = append(gs, &pb.ServiceInfo{ |
52 | Id: k, | 52 | Id: k, |
53 | - Name: conf.GlobalConf.GameConf.Name, | 53 | + Name: common.GlobalConf.GameConf.Name, |
54 | Address: v, | 54 | Address: v, |
55 | }) | 55 | }) |
56 | } | 56 | } |
cmd/httpserver/http.go
@@ -4,13 +4,11 @@ import ( | @@ -4,13 +4,11 @@ import ( | ||
4 | "fmt" | 4 | "fmt" |
5 | "os" | 5 | "os" |
6 | "os/signal" | 6 | "os/signal" |
7 | + "pro2d/common" | ||
7 | "pro2d/common/components" | 8 | "pro2d/common/components" |
8 | - "pro2d/conf" | ||
9 | - _ "pro2d/conf" | ||
10 | - "pro2d/models" | ||
11 | - "pro2d/utils/db" | ||
12 | - "pro2d/utils/etcd" | ||
13 | - "pro2d/utils/logger" | 9 | + "pro2d/common/db" |
10 | + "pro2d/common/etcd" | ||
11 | + "pro2d/common/logger" | ||
14 | "syscall" | 12 | "syscall" |
15 | ) | 13 | ) |
16 | 14 | ||
@@ -24,17 +22,21 @@ func NewAccountServer(version string, port ...string) *AccountServer { | @@ -24,17 +22,21 @@ func NewAccountServer(version string, port ...string) *AccountServer { | ||
24 | } | 22 | } |
25 | 23 | ||
26 | func (s *AccountServer) Init() error { | 24 | func (s *AccountServer) Init() error { |
27 | - //mongo 初始化 | ||
28 | - db.MongoDatabase = db.MongoClient.Database(conf.GlobalConf.AccountConf.DBName) | ||
29 | - models.InitAccountServerModels() | 25 | + //mgo init |
26 | + err := db.ConnectMongo(common.GlobalConf.AccountConf.MongoConf) | ||
30 | 27 | ||
31 | //Etcd 初始化 | 28 | //Etcd 初始化 |
32 | - var err error | ||
33 | - s.EtcdClient, err = etcd.NewEtcdClient(conf.GlobalConf.Etcd) | 29 | + s.EtcdClient, err = etcd.NewEtcdClient(common.GlobalConf.Etcd) |
34 | if err != nil { | 30 | if err != nil { |
35 | return err | 31 | return err |
36 | } | 32 | } |
37 | - s.EtcdClient.PutWithLeasePrefix(conf.GlobalConf.AccountConf.Name, conf.GlobalConf.AccountConf.ID, fmt.Sprintf("%s:%d", conf.GlobalConf.AccountConf.IP, conf.GlobalConf.AccountConf.Port), 5) | 33 | + |
34 | + //Etcd 初始化 | ||
35 | + s.EtcdClient, err = etcd.NewEtcdClient(common.GlobalConf.Etcd) | ||
36 | + if err != nil { | ||
37 | + return err | ||
38 | + } | ||
39 | + s.EtcdClient.PutWithLeasePrefix(common.GlobalConf.AccountConf.Name, common.GlobalConf.AccountConf.ID, fmt.Sprintf("%s:%d", common.GlobalConf.AccountConf.IP, common.GlobalConf.AccountConf.Port), 5) | ||
38 | return nil | 40 | return nil |
39 | } | 41 | } |
40 | 42 | ||
@@ -51,7 +53,7 @@ func main() { | @@ -51,7 +53,7 @@ func main() { | ||
51 | stopChan := make(chan os.Signal) | 53 | stopChan := make(chan os.Signal) |
52 | signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) | 54 | signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) |
53 | 55 | ||
54 | - web := NewAccountServer("v1", fmt.Sprintf(":%d", conf.GlobalConf.AccountConf.Port)) | 56 | + web := NewAccountServer("v1", fmt.Sprintf(":%d", common.GlobalConf.AccountConf.Port)) |
55 | web.BindHandler(&AccountAction{HttpServer: web}) | 57 | web.BindHandler(&AccountAction{HttpServer: web}) |
56 | go func() { | 58 | go func() { |
57 | err <- web.Start() | 59 | err <- web.Start() |
cmd/test/client.go
@@ -7,8 +7,8 @@ import ( | @@ -7,8 +7,8 @@ import ( | ||
7 | "github.com/golang/protobuf/proto" | 7 | "github.com/golang/protobuf/proto" |
8 | "net" | 8 | "net" |
9 | "pro2d/common/components" | 9 | "pro2d/common/components" |
10 | + "pro2d/common/logger" | ||
10 | "pro2d/pb" | 11 | "pro2d/pb" |
11 | - "pro2d/utils/logger" | ||
12 | "time" | 12 | "time" |
13 | ) | 13 | ) |
14 | 14 |
common/components/conn.go
@@ -5,7 +5,7 @@ import ( | @@ -5,7 +5,7 @@ import ( | ||
5 | "fmt" | 5 | "fmt" |
6 | "net" | 6 | "net" |
7 | "pro2d/common" | 7 | "pro2d/common" |
8 | - "pro2d/utils/logger" | 8 | + "pro2d/common/logger" |
9 | "sync/atomic" | 9 | "sync/atomic" |
10 | "time" | 10 | "time" |
11 | ) | 11 | ) |
@@ -84,18 +84,16 @@ func (c *Connection) Start() { | @@ -84,18 +84,16 @@ func (c *Connection) Start() { | ||
84 | c.handleTimeOut() | 84 | c.handleTimeOut() |
85 | } | 85 | } |
86 | 86 | ||
87 | -func (c *Connection) Stop() { | ||
88 | - logger.Debug("ID: %d close", c.Id) | ||
89 | - closed := atomic.LoadUint32(&c.Status) | ||
90 | - if closed == 0 { | 87 | +func (c *Connection) Stop() { |
88 | + sendTimeout := time.NewTimer(5 * time.Millisecond) | ||
89 | + defer sendTimeout.Stop() | ||
90 | + // 发送超时 | ||
91 | + select { | ||
92 | + case <-sendTimeout.C: | ||
93 | + return | ||
94 | + case c.Quit <- c: | ||
91 | return | 95 | return |
92 | } | 96 | } |
93 | - atomic.StoreUint32(&c.Status, 0) | ||
94 | - | ||
95 | - close(c.WBuffer) | ||
96 | - close(c.Quit) | ||
97 | - c.Conn.Close() | ||
98 | - c.closeCallback(c) | ||
99 | } | 97 | } |
100 | 98 | ||
101 | func (c *Connection) Send(errCode int32, cmd uint32, data []byte) error{ | 99 | func (c *Connection) Send(errCode int32, cmd uint32, data []byte) error{ |
@@ -128,7 +126,7 @@ func (c *Connection) defaultTimerCallback(conn IConnection) { | @@ -128,7 +126,7 @@ func (c *Connection) defaultTimerCallback(conn IConnection) { | ||
128 | } | 126 | } |
129 | 127 | ||
130 | func (c *Connection) write() { | 128 | func (c *Connection) write() { |
131 | - defer c.Stop() | 129 | + defer c.quitting() |
132 | 130 | ||
133 | for msg := range c.WBuffer { | 131 | for msg := range c.WBuffer { |
134 | n, err := c.writer.Write(msg) | 132 | n, err := c.writer.Write(msg) |
@@ -144,7 +142,7 @@ func (c *Connection) write() { | @@ -144,7 +142,7 @@ func (c *Connection) write() { | ||
144 | } | 142 | } |
145 | 143 | ||
146 | func (c *Connection) read() { | 144 | func (c *Connection) read() { |
147 | - defer c.Quitting() | 145 | + defer c.quitting() |
148 | c.scanner.Split(c.Server.GetSplitter().ParseMsg) | 146 | c.scanner.Split(c.Server.GetSplitter().ParseMsg) |
149 | 147 | ||
150 | for c.scanner.Scan() { | 148 | for c.scanner.Scan() { |
@@ -153,7 +151,7 @@ func (c *Connection) read() { | @@ -153,7 +151,7 @@ func (c *Connection) read() { | ||
153 | return | 151 | return |
154 | } | 152 | } |
155 | 153 | ||
156 | - req.SetSessId(c.Id) | 154 | + req.SetSession(c) |
157 | c.readFunc <- func() { | 155 | c.readFunc <- func() { |
158 | c.messageCallback(req) | 156 | c.messageCallback(req) |
159 | } | 157 | } |
@@ -167,7 +165,7 @@ func (c *Connection) read() { | @@ -167,7 +165,7 @@ func (c *Connection) read() { | ||
167 | 165 | ||
168 | //此设计目的是为了让网络数据与定时器处理都在一条协程里处理。不想加锁。。。 | 166 | //此设计目的是为了让网络数据与定时器处理都在一条协程里处理。不想加锁。。。 |
169 | func (c *Connection) listen(){ | 167 | func (c *Connection) listen(){ |
170 | - defer c.Stop() | 168 | + defer c.quitting() |
171 | 169 | ||
172 | for { | 170 | for { |
173 | select { | 171 | select { |
@@ -188,6 +186,16 @@ func (c *Connection) handleTimeOut() { | @@ -188,6 +186,16 @@ func (c *Connection) handleTimeOut() { | ||
188 | TimeOut(1*time.Second, c.handleTimeOut) | 186 | TimeOut(1*time.Second, c.handleTimeOut) |
189 | } | 187 | } |
190 | 188 | ||
191 | -func (c *Connection) Quitting() { | ||
192 | - c.Quit <- c | 189 | +func (c *Connection) quitting() { |
190 | + closed := atomic.LoadUint32(&c.Status) | ||
191 | + if closed == 0 { | ||
192 | + return | ||
193 | + } | ||
194 | + atomic.StoreUint32(&c.Status, 0) | ||
195 | + | ||
196 | + logger.Debug("ID: %d close", c.Id) | ||
197 | + close(c.WBuffer) | ||
198 | + close(c.Quit) | ||
199 | + c.Conn.Close() | ||
200 | + c.closeCallback(c) | ||
193 | } | 201 | } |
common/components/icompontents.go
1 | package components | 1 | package components |
2 | 2 | ||
3 | -//网络包头 | ||
4 | -type IHead interface { | ||
5 | - GetDataLen() uint32 //获取消息数据段长度 | ||
6 | - GetMsgID() uint32 //获取消息ID | ||
7 | - GetErrCode() int32 //获取消息错误码 | ||
8 | - GetPreserve() uint32 //获取预留数据 | ||
9 | -} | ||
10 | - | ||
11 | -//网络包 | ||
12 | -type IMessage interface { | ||
13 | - IHead | ||
14 | - GetHeader() IHead //获取消息头 | ||
15 | - SetHeader(header IHead) //设置消息头 | ||
16 | - | ||
17 | - GetData() []byte //获取消息内容 | ||
18 | - SetData([]byte) //设置消息内容 | ||
19 | - | ||
20 | - SetSessId(int) //设置连接id | ||
21 | - GetSessId() int //获取连接id | ||
22 | -} | ||
23 | - | ||
24 | -//网络拆包解包器 | ||
25 | -type ISplitter interface { | ||
26 | - UnPack([]byte) (IMessage, error) | ||
27 | - Pack(cmd uint32, data []byte, errcode int32, preserve uint32) ([]byte, error) | ||
28 | - ParseMsg (data []byte, atEOF bool) (advance int, token []byte, err error) | ||
29 | - GetHeadLen() uint32 | ||
30 | -} | ||
31 | - | ||
32 | -type ConnectionCallback func(IConnection) | ||
33 | -type CloseCallback func(IConnection) | ||
34 | -type MessageCallback func(IMessage) | ||
35 | -type TimerCallback func(IConnection) | ||
36 | - | ||
37 | -//链接 | ||
38 | -type IConnection interface { | ||
39 | - GetID() int | ||
40 | - Start() | ||
41 | - Stop() | ||
42 | - Send(code int32, cmd uint32, b []byte) error | ||
43 | - | ||
44 | - SetConnectionCallback(ConnectionCallback) | ||
45 | - SetMessageCallback(MessageCallback) | ||
46 | - SetCloseCallback(CloseCallback) | ||
47 | - SetTimerCallback(TimerCallback) | ||
48 | -} | ||
49 | - | ||
50 | -//server | ||
51 | -type IServer interface { | ||
52 | - Start() error | ||
53 | - Stop() | ||
54 | - | ||
55 | - GetSplitter() ISplitter | ||
56 | - GetIConnection(id int) IConnection | ||
57 | - GetPlugin() IPlugin | ||
58 | - | ||
59 | - SetConnectionCallback(ConnectionCallback) | ||
60 | - SetMessageCallback(MessageCallback) | ||
61 | - SetCloseCallback(CloseCallback) | ||
62 | - SetTimerCallback(TimerCallback) | ||
63 | -} | ||
64 | - | ||
65 | -//httpserver | ||
66 | -type IHttp interface { | ||
67 | - Start() error | ||
68 | - Stop() | ||
69 | - BindHandler(interface{}) | ||
70 | -} | ||
71 | - | ||
72 | -type ActionHandler func (conn IConnection, msg IMessage) (int32, interface{}) | ||
73 | -//用于热更逻辑的插件接口 | ||
74 | -type IPlugin interface { | ||
75 | - LoadPlugin() error | ||
76 | - GetAction(uint32) interface{} | ||
77 | -} | ||
78 | \ No newline at end of file | 3 | \ No newline at end of file |
4 | +//----------------- | ||
5 | +//----net start---- | ||
6 | +//----------------- | ||
7 | +type ( | ||
8 | + //网络包头 | ||
9 | + IHead interface { | ||
10 | + GetDataLen() uint32 //获取消息数据段长度 | ||
11 | + GetMsgID() uint32 //获取消息ID | ||
12 | + GetErrCode() int32 //获取消息错误码 | ||
13 | + GetPreserve() uint32 //获取预留数据 | ||
14 | + } | ||
15 | + //网络包 | ||
16 | + IMessage interface { | ||
17 | + IHead | ||
18 | + GetHeader() IHead //获取消息头 | ||
19 | + SetHeader(header IHead) //设置消息头 | ||
20 | + | ||
21 | + GetData() []byte //获取消息内容 | ||
22 | + SetData([]byte) //设置消息内容 | ||
23 | + | ||
24 | + SetSession(IConnection) //设置连接 | ||
25 | + GetSession() IConnection //获取连接 | ||
26 | + } | ||
27 | + //网络拆包解包器 | ||
28 | + ISplitter interface { | ||
29 | + UnPack([]byte) (IMessage, error) | ||
30 | + Pack(cmd uint32, data []byte, errcode int32, preserve uint32) ([]byte, error) | ||
31 | + ParseMsg(data []byte, atEOF bool) (advance int, token []byte, err error) | ||
32 | + GetHeadLen() uint32 | ||
33 | + } | ||
34 | + ConnectionCallback func(IConnection) | ||
35 | + CloseCallback func(IConnection) | ||
36 | + MessageCallback func(IMessage) | ||
37 | + TimerCallback func(IConnection) | ||
38 | + //链接 | ||
39 | + IConnection interface { | ||
40 | + GetID() int | ||
41 | + Start() | ||
42 | + Stop() | ||
43 | + Send(code int32, cmd uint32, b []byte) error | ||
44 | + | ||
45 | + SetConnectionCallback(ConnectionCallback) | ||
46 | + SetMessageCallback(MessageCallback) | ||
47 | + SetCloseCallback(CloseCallback) | ||
48 | + SetTimerCallback(TimerCallback) | ||
49 | + } | ||
50 | + //server | ||
51 | + IServer interface { | ||
52 | + Start() error | ||
53 | + Stop() | ||
54 | + | ||
55 | + GetSplitter() ISplitter | ||
56 | + GetIConnection(id int) IConnection | ||
57 | + GetPlugin() IPlugin | ||
58 | + GetAction(uint32) interface{} | ||
59 | + | ||
60 | + SetConnectionCallback(ConnectionCallback) | ||
61 | + SetMessageCallback(MessageCallback) | ||
62 | + SetCloseCallback(CloseCallback) | ||
63 | + SetTimerCallback(TimerCallback) | ||
64 | + } | ||
65 | + | ||
66 | + //httpserver | ||
67 | + IHttp interface { | ||
68 | + Start() error | ||
69 | + Stop() | ||
70 | + BindHandler(interface{}) | ||
71 | + } | ||
72 | + ActionHandler func(conn IConnection, msg IMessage) (int32, interface{}) | ||
73 | + //用于热更逻辑的插件接口 | ||
74 | + IPlugin interface { | ||
75 | + LoadPlugin() error | ||
76 | + SetActions(map[interface{}]interface{}) | ||
77 | + GetAction(uint32) interface{} | ||
78 | + } | ||
79 | + | ||
80 | + | ||
81 | +) | ||
82 | + | ||
83 | +//----------------- | ||
84 | +//-----db start---- | ||
85 | +//----------------- | ||
86 | +type ( | ||
87 | + IDB interface { | ||
88 | + CreateTable() error | ||
89 | + | ||
90 | + Create() (interface{}, error) | ||
91 | + Load() error | ||
92 | + FindOne() error | ||
93 | + UpdateProperty(key string, val interface{}) error | ||
94 | + UpdateProperties(properties map[string]interface{}) error | ||
95 | + | ||
96 | + SetUnique(key string) (string, error) | ||
97 | + } | ||
98 | + | ||
99 | + ISchema interface { | ||
100 | + Init() | ||
101 | + GetDB() IDB | ||
102 | + | ||
103 | + GetPri() interface{} | ||
104 | + GetSchema() interface{} | ||
105 | + GetSchemaName() string | ||
106 | + | ||
107 | + Load() error | ||
108 | + Create() error | ||
109 | + Update() | ||
110 | + | ||
111 | + SetProperty(key string, val interface{}) | ||
112 | + SetProperties(properties map[string]interface{}) | ||
113 | + } | ||
114 | +) | ||
115 | + | ||
116 | +//----------------- | ||
117 | +//-----db end------ | ||
118 | +//----------------- |
common/components/pbsplitter.go
@@ -35,7 +35,7 @@ type PBMessage struct { | @@ -35,7 +35,7 @@ type PBMessage struct { | ||
35 | Head IHead | 35 | Head IHead |
36 | Body []byte | 36 | Body []byte |
37 | 37 | ||
38 | - SessionID int | 38 | + conn IConnection |
39 | } | 39 | } |
40 | 40 | ||
41 | 41 | ||
@@ -54,12 +54,12 @@ func (m *PBMessage) SetData(b []byte) { | @@ -54,12 +54,12 @@ func (m *PBMessage) SetData(b []byte) { | ||
54 | m.Body = b | 54 | m.Body = b |
55 | } | 55 | } |
56 | 56 | ||
57 | -func (m *PBMessage) SetSessId(id int) { | ||
58 | - m.SessionID = id | 57 | +func (m *PBMessage) SetSession(connection IConnection) { |
58 | + m.conn = connection | ||
59 | } | 59 | } |
60 | 60 | ||
61 | -func (m *PBMessage) GetSessId() int { | ||
62 | - return m.SessionID | 61 | +func (m *PBMessage) GetSession() IConnection { |
62 | + return m.conn | ||
63 | } | 63 | } |
64 | 64 | ||
65 | 65 |
common/components/plugin.go
@@ -2,8 +2,8 @@ package components | @@ -2,8 +2,8 @@ package components | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "plugin" | 4 | "plugin" |
5 | + "pro2d/common/logger" | ||
5 | "pro2d/pb" | 6 | "pro2d/pb" |
6 | - "pro2d/utils/logger" | ||
7 | "sync" | 7 | "sync" |
8 | ) | 8 | ) |
9 | 9 | ||
@@ -43,11 +43,7 @@ func (p *Plugin) LoadPlugin() error { | @@ -43,11 +43,7 @@ func (p *Plugin) LoadPlugin() error { | ||
43 | 43 | ||
44 | if x, ok := f.(func()map[interface{}]interface{}); ok { | 44 | if x, ok := f.(func()map[interface{}]interface{}); ok { |
45 | logger.Debug("func LoadPlugin GetActionMap success...") | 45 | logger.Debug("func LoadPlugin GetActionMap success...") |
46 | - am := x() | ||
47 | - for k, v := range am { | ||
48 | - p.Actions.Delete(k) | ||
49 | - p.Actions.Store(k, v) | ||
50 | - } | 46 | + p.SetActions(x()) |
51 | } | 47 | } |
52 | 48 | ||
53 | return nil | 49 | return nil |
@@ -60,3 +56,11 @@ func (p *Plugin) GetAction(cmd uint32) interface{} { | @@ -60,3 +56,11 @@ func (p *Plugin) GetAction(cmd uint32) interface{} { | ||
60 | } | 56 | } |
61 | return f | 57 | return f |
62 | } | 58 | } |
59 | + | ||
60 | +func (p *Plugin) SetActions(am map[interface{}]interface{}) { | ||
61 | + for k, v := range am { | ||
62 | + cmd := k.(pb.ProtoCode) | ||
63 | + p.Actions.Delete(cmd) | ||
64 | + p.Actions.Store(cmd, v) | ||
65 | + } | ||
66 | +} |
common/components/server.go
@@ -3,43 +3,43 @@ package components | @@ -3,43 +3,43 @@ package components | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | "net" | 5 | "net" |
6 | - "pro2d/utils/logger" | 6 | + "pro2d/common/logger" |
7 | "sync" | 7 | "sync" |
8 | ) | 8 | ) |
9 | 9 | ||
10 | -type Option func(*Server) | 10 | +type ServerOption func(*Server) |
11 | 11 | ||
12 | -func WithPlugin(iPlugin IPlugin) Option { | 12 | +func WithPlugin(iPlugin IPlugin) ServerOption { |
13 | return func(server *Server) { | 13 | return func(server *Server) { |
14 | server.plugins = iPlugin | 14 | server.plugins = iPlugin |
15 | } | 15 | } |
16 | } | 16 | } |
17 | 17 | ||
18 | -func WithSplitter(splitter ISplitter) Option { | 18 | +func WithSplitter(splitter ISplitter) ServerOption { |
19 | return func(server *Server) { | 19 | return func(server *Server) { |
20 | server.splitter = splitter | 20 | server.splitter = splitter |
21 | } | 21 | } |
22 | } | 22 | } |
23 | 23 | ||
24 | -func WithConnCbk(cb ConnectionCallback) Option { | 24 | +func WithConnCbk(cb ConnectionCallback) ServerOption { |
25 | return func(server *Server) { | 25 | return func(server *Server) { |
26 | server.connectionCallback = cb | 26 | server.connectionCallback = cb |
27 | } | 27 | } |
28 | } | 28 | } |
29 | 29 | ||
30 | -func WithMsgCbk(cb MessageCallback) Option { | 30 | +func WithMsgCbk(cb MessageCallback) ServerOption { |
31 | return func(server *Server) { | 31 | return func(server *Server) { |
32 | server.messageCallback = cb | 32 | server.messageCallback = cb |
33 | } | 33 | } |
34 | } | 34 | } |
35 | 35 | ||
36 | -func WithCloseCbk(cb CloseCallback) Option { | 36 | +func WithCloseCbk(cb CloseCallback) ServerOption { |
37 | return func(server *Server) { | 37 | return func(server *Server) { |
38 | server.closeCallback = cb | 38 | server.closeCallback = cb |
39 | } | 39 | } |
40 | } | 40 | } |
41 | 41 | ||
42 | -func WithTimerCbk(cb TimerCallback) Option { | 42 | +func WithTimerCbk(cb TimerCallback) ServerOption { |
43 | return func(server *Server) { | 43 | return func(server *Server) { |
44 | server.timerCallback = cb | 44 | server.timerCallback = cb |
45 | } | 45 | } |
@@ -50,7 +50,6 @@ type Server struct { | @@ -50,7 +50,6 @@ type Server struct { | ||
50 | PluginPath string | 50 | PluginPath string |
51 | plugins IPlugin | 51 | plugins IPlugin |
52 | splitter ISplitter | 52 | splitter ISplitter |
53 | - actionHandlers sync.Map | ||
54 | 53 | ||
55 | connectionCallback ConnectionCallback | 54 | connectionCallback ConnectionCallback |
56 | messageCallback MessageCallback | 55 | messageCallback MessageCallback |
@@ -61,7 +60,7 @@ type Server struct { | @@ -61,7 +60,7 @@ type Server struct { | ||
61 | Clients *sync.Map | 60 | Clients *sync.Map |
62 | } | 61 | } |
63 | 62 | ||
64 | -func NewServer(port int, options ...Option) IServer { | 63 | +func NewServer(port int, options ...ServerOption) IServer { |
65 | s := &Server{ | 64 | s := &Server{ |
66 | port: port, | 65 | port: port, |
67 | Clients: new(sync.Map), | 66 | Clients: new(sync.Map), |
@@ -89,6 +88,10 @@ func (s *Server) GetPlugin() IPlugin { | @@ -89,6 +88,10 @@ func (s *Server) GetPlugin() IPlugin { | ||
89 | return s.plugins | 88 | return s.plugins |
90 | } | 89 | } |
91 | 90 | ||
91 | +func (s *Server) GetAction(cmd uint32) interface{} { | ||
92 | + return s.plugins.GetAction(cmd) | ||
93 | +} | ||
94 | + | ||
92 | func (s *Server) SetConnectionCallback(cb ConnectionCallback) { | 95 | func (s *Server) SetConnectionCallback(cb ConnectionCallback) { |
93 | s.connectionCallback = cb | 96 | s.connectionCallback = cb |
94 | } | 97 | } |
@@ -105,22 +108,6 @@ func (s *Server) SetTimerCallback(cb TimerCallback) { | @@ -105,22 +108,6 @@ func (s *Server) SetTimerCallback(cb TimerCallback) { | ||
105 | s.timerCallback = cb | 108 | s.timerCallback = cb |
106 | } | 109 | } |
107 | 110 | ||
108 | -func (s *Server) newConnection(conn IConnection) { | ||
109 | - s.Clients.Store(conn.GetID(), conn) | ||
110 | - | ||
111 | - conn.SetConnectionCallback(s.connectionCallback) | ||
112 | - conn.SetCloseCallback(s.removeConnection) | ||
113 | - conn.SetMessageCallback(s.messageCallback) | ||
114 | - conn.SetTimerCallback(s.timerCallback) | ||
115 | - | ||
116 | - go conn.Start() | ||
117 | -} | ||
118 | - | ||
119 | -func (s *Server) removeConnection(conn IConnection) { | ||
120 | - s.closeCallback(conn) | ||
121 | - s.Clients.Delete(conn.GetID()) | ||
122 | -} | ||
123 | - | ||
124 | func (s *Server) Start() error { | 111 | func (s *Server) Start() error { |
125 | if err := s.plugins.LoadPlugin(); err != nil { | 112 | if err := s.plugins.LoadPlugin(); err != nil { |
126 | return err | 113 | return err |
@@ -148,9 +135,26 @@ func (s *Server) Start() error { | @@ -148,9 +135,26 @@ func (s *Server) Start() error { | ||
148 | 135 | ||
149 | func (s *Server)Stop() { | 136 | func (s *Server)Stop() { |
150 | StopTimer() | 137 | StopTimer() |
138 | + | ||
151 | s.Clients.Range(func(key, value interface{}) bool { | 139 | s.Clients.Range(func(key, value interface{}) bool { |
152 | client := value.(IConnection) | 140 | client := value.(IConnection) |
153 | client.Stop() | 141 | client.Stop() |
154 | return true | 142 | return true |
155 | }) | 143 | }) |
156 | } | 144 | } |
145 | + | ||
146 | +func (s *Server) newConnection(conn IConnection) { | ||
147 | + s.Clients.Store(conn.GetID(), conn) | ||
148 | + | ||
149 | + conn.SetConnectionCallback(s.connectionCallback) | ||
150 | + conn.SetCloseCallback(s.removeConnection) | ||
151 | + conn.SetMessageCallback(s.messageCallback) | ||
152 | + conn.SetTimerCallback(s.timerCallback) | ||
153 | + | ||
154 | + go conn.Start() | ||
155 | +} | ||
156 | + | ||
157 | +func (s *Server) removeConnection(conn IConnection) { | ||
158 | + s.closeCallback(conn) | ||
159 | + s.Clients.Delete(conn.GetID()) | ||
160 | +} |
conf/conf.go renamed to common/conf.go
1 | -package conf | 1 | +package common |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "encoding/json" | 4 | "encoding/json" |
5 | "fmt" | 5 | "fmt" |
6 | "gopkg.in/yaml.v3" | 6 | "gopkg.in/yaml.v3" |
7 | "io/ioutil" | 7 | "io/ioutil" |
8 | - "pro2d/utils" | ||
9 | - "pro2d/utils/db" | ||
10 | - "pro2d/utils/logger" | 8 | + "pro2d/common/logger" |
11 | "strings" | 9 | "strings" |
12 | ) | 10 | ) |
13 | 11 | ||
@@ -29,6 +27,7 @@ type MongoConf struct { | @@ -29,6 +27,7 @@ type MongoConf struct { | ||
29 | Port int `yaml:"port"` | 27 | Port int `yaml:"port"` |
30 | TimeOut int `yaml:"timeout"` | 28 | TimeOut int `yaml:"timeout"` |
31 | MaxNum int `yaml:"maxnum"` | 29 | MaxNum int `yaml:"maxnum"` |
30 | + DBName string `yaml:"dbname"` | ||
32 | } | 31 | } |
33 | 32 | ||
34 | type SConf struct { | 33 | type SConf struct { |
@@ -36,7 +35,8 @@ type SConf struct { | @@ -36,7 +35,8 @@ type SConf struct { | ||
36 | Name string `yaml:"name"` | 35 | Name string `yaml:"name"` |
37 | IP string `yaml:"ip"` | 36 | IP string `yaml:"ip"` |
38 | Port int `yaml:"port"` | 37 | Port int `yaml:"port"` |
39 | - DBName string `yaml:"dbname"` | 38 | + DebugPort int `yaml:"debugport"` |
39 | + MongoConf *MongoConf `yaml:"mongo"` | ||
40 | WorkerPoolSize int `yaml:"pool_size"` | 40 | WorkerPoolSize int `yaml:"pool_size"` |
41 | PluginPath string `yaml:"plugin_path"` | 41 | PluginPath string `yaml:"plugin_path"` |
42 | } | 42 | } |
@@ -65,28 +65,27 @@ type LogConn struct { | @@ -65,28 +65,27 @@ type LogConn struct { | ||
65 | } | 65 | } |
66 | 66 | ||
67 | type LogConf struct { | 67 | type LogConf struct { |
68 | - TimeFormat string `yaml:"TimeFormat" json:"TimeFormat"` | ||
69 | - LogConsole *LogConsole `yaml:"Console" json:"Console"` | ||
70 | - LogFile *LogFile `yaml:"File" json:"File"` | ||
71 | - LogConn *LogConn `yaml:"Conn" json:"Conn"` | 68 | + TimeFormat string `yaml:"TimeFormat" json:"TimeFormat"` |
69 | + LogConsole *LogConsole `yaml:"Console" json:"Console"` | ||
70 | + LogFile *LogFile `yaml:"File" json:"File"` | ||
71 | + LogConn *LogConn `yaml:"Conn" json:"Conn"` | ||
72 | } | 72 | } |
73 | 73 | ||
74 | type ServerConf struct { | 74 | type ServerConf struct { |
75 | - ID string `yaml:"id"` | ||
76 | - Name string `yaml:"name"` | ||
77 | - WorkerID int64 `yaml:"workerid"` | ||
78 | - DatacenterID int64 `yaml:"datacenterid"` | ||
79 | - MongoConf *MongoConf `yaml:"mongo"` | ||
80 | - AccountConf *SConf `yaml:"server_account"` | ||
81 | - GameConf *SConf `yaml:"server_game"` | 75 | + ID string `yaml:"id"` |
76 | + Name string `yaml:"name"` | ||
77 | + WorkerID int64 `yaml:"workerid"` | ||
78 | + DatacenterID int64 `yaml:"datacenterid"` | ||
79 | + AccountConf *SConf `yaml:"server_account"` | ||
80 | + GameConf *SConf `yaml:"server_game"` | ||
82 | RedisConf *RedisConf `yaml:"redis"` | 81 | RedisConf *RedisConf `yaml:"redis"` |
83 | - LogConf *LogConf `yaml:"logconf" json:"logconf"` | ||
84 | - Etcd *Etcd `yaml:"etcd"` | 82 | + LogConf *LogConf `yaml:"logconf" json:"logconf"` |
83 | + Etcd *Etcd `yaml:"etcd"` | ||
85 | } | 84 | } |
86 | 85 | ||
87 | var( | 86 | var( |
88 | GlobalConf ServerConf | 87 | GlobalConf ServerConf |
89 | - SnowFlack *utils.Snowflake | 88 | + SnowFlack *Snowflake |
90 | ) | 89 | ) |
91 | 90 | ||
92 | func init() { | 91 | func init() { |
@@ -114,11 +113,5 @@ func init() { | @@ -114,11 +113,5 @@ func init() { | ||
114 | } | 113 | } |
115 | 114 | ||
116 | //初始化雪花算法 | 115 | //初始化雪花算法 |
117 | - SnowFlack = utils.NewSnowflake(GlobalConf.WorkerID, GlobalConf.DatacenterID) | ||
118 | - | ||
119 | - err = db.Connect(GlobalConf.MongoConf.User, GlobalConf.MongoConf.Password, GlobalConf.MongoConf.Host, GlobalConf.MongoConf.Port, GlobalConf.MongoConf.MaxNum, GlobalConf.MongoConf.TimeOut) | ||
120 | - if err != nil { | ||
121 | - logger.Error("connect db err: %v", err) | ||
122 | - } | ||
123 | - | 116 | + SnowFlack = NewSnowflake(GlobalConf.WorkerID, GlobalConf.DatacenterID) |
124 | } | 117 | } |
125 | \ No newline at end of file | 118 | \ No newline at end of file |
@@ -0,0 +1,104 @@ | @@ -0,0 +1,104 @@ | ||
1 | +package db | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "fmt" | ||
6 | + "go.mongodb.org/mongo-driver/bson" | ||
7 | + "go.mongodb.org/mongo-driver/mongo" | ||
8 | + "go.mongodb.org/mongo-driver/mongo/options" | ||
9 | + "go.mongodb.org/mongo-driver/x/bsonx" | ||
10 | + "pro2d/common/components" | ||
11 | + "sort" | ||
12 | + "strings" | ||
13 | +) | ||
14 | + | ||
15 | +var ( | ||
16 | + mongoClient *mongo.Client | ||
17 | + mongoDatabase *mongo.Database | ||
18 | +) | ||
19 | + | ||
20 | +type MgoColl struct { | ||
21 | + components.IDB | ||
22 | + Schema components.ISchema | ||
23 | + | ||
24 | + dbname string | ||
25 | + coll *mongo.Collection | ||
26 | +} | ||
27 | + | ||
28 | +func NewMongoColl(dbname string, schema components.ISchema) *MgoColl { | ||
29 | + m := &MgoColl{ | ||
30 | + dbname: dbname, | ||
31 | + coll: DB().Collection(dbname), | ||
32 | + Schema: schema, | ||
33 | + } | ||
34 | + return m | ||
35 | +} | ||
36 | + | ||
37 | +func (m *MgoColl) CreateTable() error { | ||
38 | + colls, _ := DB().ListCollectionNames(context.TODO(), bson.D{}) | ||
39 | + pos := sort.SearchStrings(colls, m.dbname) | ||
40 | + if pos != len(colls) { | ||
41 | + if m.dbname == colls[pos] { | ||
42 | + return DB().CreateCollection(context.TODO(), m.dbname) | ||
43 | + } | ||
44 | + } | ||
45 | + return DB().CreateCollection(context.TODO(), m.dbname) | ||
46 | +} | ||
47 | + | ||
48 | +func (m *MgoColl) Create() (interface{}, error){ | ||
49 | + return m.coll.InsertOne(context.TODO(), m.Schema.GetSchema()) | ||
50 | +} | ||
51 | + | ||
52 | +func (m *MgoColl) Load() error{ | ||
53 | + r := m.coll.FindOne(context.TODO(), m.Schema.GetPri()) | ||
54 | + err := r.Decode(m.Schema.GetSchema()) | ||
55 | + if err != nil { | ||
56 | + return err | ||
57 | + } | ||
58 | + return nil | ||
59 | +} | ||
60 | + | ||
61 | +// 查询单个 | ||
62 | +func (m *MgoColl) FindOne() error { | ||
63 | + singleResult := m.coll.FindOne(context.TODO(), m.Schema.GetPri()) | ||
64 | + return singleResult.Decode(m.Schema.GetSchema()) | ||
65 | +} | ||
66 | + | ||
67 | +func (m *MgoColl) UpdateOne(filter interface{}, update interface{})*mongo.UpdateResult { | ||
68 | + res, err := m.coll.UpdateOne(context.TODO(), filter, bson.D{{"$set", update}}) | ||
69 | + if err != nil { | ||
70 | + return nil | ||
71 | + } | ||
72 | + return res | ||
73 | +} | ||
74 | + | ||
75 | +func (m *MgoColl) UpdateProperty(key string, val interface{}) error { | ||
76 | + _, err := m.coll.UpdateOne(context.TODO(), m.Schema.GetPri(), bson.D{{"$set", bson.M{strings.ToLower(key): val}}}) | ||
77 | + return err | ||
78 | +} | ||
79 | + | ||
80 | +func (m *MgoColl) UpdateProperties(properties map[string]interface{}) error { | ||
81 | + _, err := m.coll.UpdateOne(context.TODO(), m.Schema.GetPri(), properties) | ||
82 | + return err | ||
83 | +} | ||
84 | + | ||
85 | +//索引 | ||
86 | +func (m *MgoColl) SetUnique(key string) (string, error){ | ||
87 | + return m.coll.Indexes().CreateOne( | ||
88 | + context.Background(), | ||
89 | + mongo.IndexModel{ | ||
90 | + Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, | ||
91 | + Options: options.Index().SetUnique(true), | ||
92 | + }, | ||
93 | + ) | ||
94 | +} | ||
95 | + | ||
96 | +func (m *MgoColl) Delete(key string, value interface{}) int64 { | ||
97 | + filter := bson.D{ {key, value}} | ||
98 | + count, err := m.coll.DeleteOne(context.TODO(), filter, nil) | ||
99 | + if err != nil { | ||
100 | + fmt.Println(err) | ||
101 | + } | ||
102 | + return count.DeletedCount | ||
103 | + | ||
104 | +} |
@@ -0,0 +1,148 @@ | @@ -0,0 +1,148 @@ | ||
1 | +package db | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "fmt" | ||
6 | + "go.mongodb.org/mongo-driver/bson" | ||
7 | + "go.mongodb.org/mongo-driver/mongo" | ||
8 | + "go.mongodb.org/mongo-driver/mongo/options" | ||
9 | + "go.mongodb.org/mongo-driver/mongo/readpref" | ||
10 | + "go.mongodb.org/mongo-driver/x/bsonx" | ||
11 | + "pro2d/common" | ||
12 | + "pro2d/common/logger" | ||
13 | + "reflect" | ||
14 | + "sort" | ||
15 | + "strings" | ||
16 | + "time" | ||
17 | +) | ||
18 | + | ||
19 | +func DB() *mongo.Database { | ||
20 | + return mongoDatabase | ||
21 | +} | ||
22 | + | ||
23 | +func ConnectMongo(conf *common.MongoConf) error { | ||
24 | + var uri string | ||
25 | + if conf.User!= "" { | ||
26 | + //uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?w=majority", conf.User, conf.Password, conf.Host, conf.Port, conf.DBName) | ||
27 | + uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/?w=majority", conf.User, conf.Password, conf.Host, conf.Port) | ||
28 | + }else { | ||
29 | + //uri = fmt.Sprintf("mongodb://%s:%d/%s?w=majority", conf.Host, conf.Port, conf.DBName) | ||
30 | + uri = fmt.Sprintf("mongodb://%s:%d/?w=majority", conf.Host, conf.Port) | ||
31 | + } | ||
32 | + // 设置连接超时时间 | ||
33 | + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(conf.TimeOut) * time.Second) | ||
34 | + defer cancel() | ||
35 | + // 通过传进来的uri连接相关的配置 | ||
36 | + o := options.Client().ApplyURI(uri) | ||
37 | + // 设置最大连接数 - 默认是100 ,不设置就是最大 max 64 | ||
38 | + o.SetMaxPoolSize(uint64(conf.MaxNum)) | ||
39 | + // 发起链接 | ||
40 | + var err error | ||
41 | + mongoClient, err = mongo.Connect(ctx, o) | ||
42 | + if err != nil { | ||
43 | + return err | ||
44 | + } | ||
45 | + // 判断服务是不是可用 | ||
46 | + if err = mongoClient.Ping(context.Background(), readpref.Primary()); err != nil { | ||
47 | + return err | ||
48 | + } | ||
49 | + | ||
50 | + mongoDatabase = mongoClient.Database(conf.DBName) | ||
51 | + return nil | ||
52 | +} | ||
53 | + | ||
54 | +func CloseMongo(){ | ||
55 | + mongoClient.Disconnect(context.TODO()) | ||
56 | +} | ||
57 | + | ||
58 | +func CreateTable(tb string) error { | ||
59 | + colls, _ := DB().ListCollectionNames(context.TODO(), bson.D{}) | ||
60 | + pos := sort.SearchStrings(colls, tb) | ||
61 | + if pos != len(colls) { | ||
62 | + if tb == colls[pos] { | ||
63 | + return DB().CreateCollection(context.TODO(), tb) | ||
64 | + } | ||
65 | + } | ||
66 | + return DB().CreateCollection(context.TODO(), tb) | ||
67 | +} | ||
68 | + | ||
69 | +func FindOne(pri interface{}, schema interface{}) error { | ||
70 | + r := mongoDatabase.Collection(GetCollName(schema)).FindOne(context.TODO(), pri) | ||
71 | + return r.Decode(schema) | ||
72 | +} | ||
73 | + | ||
74 | +func GetBsonD(key string, value interface{}) interface{} { | ||
75 | + return bson.D{ {key, value}} | ||
76 | +} | ||
77 | + | ||
78 | +func GetBsonM(key string, value interface{}) interface{} { | ||
79 | + return bson.M{key: value} | ||
80 | +} | ||
81 | + | ||
82 | +func GetSchemaType(schema interface{}) reflect.Type { | ||
83 | + s := reflect.TypeOf(schema) | ||
84 | + if s.Kind() == reflect.Ptr { | ||
85 | + s = reflect.TypeOf(schema).Elem() | ||
86 | + } | ||
87 | + return s | ||
88 | +} | ||
89 | + | ||
90 | +func GetCollName(schema interface{}) string { | ||
91 | + return strings.ToLower(GetSchemaType(schema).Name()) | ||
92 | +} | ||
93 | + | ||
94 | +func GetPriKey(schema interface{}) string { | ||
95 | + s := GetSchemaType(schema) | ||
96 | + | ||
97 | + var pri string | ||
98 | + for i := 0; i < s.NumField(); i++ { | ||
99 | + if s.Field(i).Tag.Get("pri") == "1" { | ||
100 | + pri = strings.ToLower(s.Field(i).Name) | ||
101 | + break | ||
102 | + } | ||
103 | + } | ||
104 | + return pri | ||
105 | +} | ||
106 | + | ||
107 | +func FindIndex(schema interface{}) (string, []string){ | ||
108 | + s := GetSchemaType(schema) | ||
109 | + | ||
110 | + var index []string | ||
111 | + for i := 0; i < s.NumField(); i++ { | ||
112 | + if s.Field(i).Tag.Get("index") != "" { | ||
113 | + js := strings.Split(s.Field(i).Tag.Get("json"), ",") | ||
114 | + if len(js) == 0 { | ||
115 | + continue | ||
116 | + } | ||
117 | + index = append(index, js[0]) | ||
118 | + } | ||
119 | + } | ||
120 | + return strings.ToLower(s.Name()), index | ||
121 | +} | ||
122 | + | ||
123 | +func SetUnique(coll, key string) (string, error){ | ||
124 | + return DB().Collection(coll).Indexes().CreateOne( | ||
125 | + context.TODO(), | ||
126 | + mongo.IndexModel{ | ||
127 | + Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, | ||
128 | + Options: options.Index().SetUnique(true), | ||
129 | + }, | ||
130 | + ) | ||
131 | +} | ||
132 | + | ||
133 | +func InitDoc(schema ...interface{}) { | ||
134 | + for _, s := range schema { | ||
135 | + coll, keys := FindIndex(s) | ||
136 | + CreateTable(coll) | ||
137 | + for _, index := range keys { | ||
138 | + | ||
139 | + logger.Debug("InitDoc collect: %v, createIndex: %s", coll, index) | ||
140 | + res, err := SetUnique(coll, index) | ||
141 | + if err != nil { | ||
142 | + logger.Error("InitDoc unique: %s, err: %v", res, err) | ||
143 | + continue | ||
144 | + } | ||
145 | + } | ||
146 | + } | ||
147 | + | ||
148 | +} | ||
0 | \ No newline at end of file | 149 | \ No newline at end of file |
utils/db/redis.go renamed to common/db/redis.go
utils/etcd/etcd.go renamed to common/etcd/etcd.go
@@ -4,8 +4,8 @@ import ( | @@ -4,8 +4,8 @@ import ( | ||
4 | "context" | 4 | "context" |
5 | "fmt" | 5 | "fmt" |
6 | clientv3 "go.etcd.io/etcd/client/v3" | 6 | clientv3 "go.etcd.io/etcd/client/v3" |
7 | - "pro2d/conf" | ||
8 | - "pro2d/utils/logger" | 7 | + "pro2d/common" |
8 | + "pro2d/common/logger" | ||
9 | "time" | 9 | "time" |
10 | ) | 10 | ) |
11 | 11 | ||
@@ -13,7 +13,7 @@ type EtcdClient struct { | @@ -13,7 +13,7 @@ type EtcdClient struct { | ||
13 | etcd *clientv3.Client | 13 | etcd *clientv3.Client |
14 | } | 14 | } |
15 | 15 | ||
16 | -func NewEtcdClient(conf *conf.Etcd) (*EtcdClient, error) { | 16 | +func NewEtcdClient(conf *common.Etcd) (*EtcdClient, error) { |
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, |
utils/etcd/etcd_test.go renamed to common/etcd/etcd_test.go
@@ -5,23 +5,23 @@ import ( | @@ -5,23 +5,23 @@ import ( | ||
5 | "fmt" | 5 | "fmt" |
6 | "go.etcd.io/etcd/api/v3/mvccpb" | 6 | "go.etcd.io/etcd/api/v3/mvccpb" |
7 | clientv3 "go.etcd.io/etcd/client/v3" | 7 | clientv3 "go.etcd.io/etcd/client/v3" |
8 | - "pro2d/conf" | ||
9 | - "pro2d/utils/logger" | 8 | + "pro2d/common" |
9 | + "pro2d/common/logger" | ||
10 | "testing" | 10 | "testing" |
11 | ) | 11 | ) |
12 | 12 | ||
13 | func TestEtcdClient_GetByPrefix(t *testing.T) { | 13 | func TestEtcdClient_GetByPrefix(t *testing.T) { |
14 | - etcd, err := NewEtcdClient(conf.GlobalConf.Etcd) | 14 | + etcd, err := NewEtcdClient(common.GlobalConf.Etcd) |
15 | if err != nil { | 15 | if err != nil { |
16 | logger.Error(err) | 16 | logger.Error(err) |
17 | return | 17 | return |
18 | } | 18 | } |
19 | - gameInfo := etcd.GetByPrefix(conf.GlobalConf.AccountConf.Name) | 19 | + gameInfo := etcd.GetByPrefix(common.GlobalConf.AccountConf.Name) |
20 | for k, v := range gameInfo { | 20 | for k, v := range gameInfo { |
21 | logger.Debug("game info key: %v val: %v", k, v) | 21 | logger.Debug("game info key: %v val: %v", k, v) |
22 | } | 22 | } |
23 | 23 | ||
24 | - rch := etcd.etcd.Watch(context.Background(), fmt.Sprintf("/%s/", conf.GlobalConf.AccountConf.Name), clientv3.WithPrefix()) | 24 | + rch := etcd.etcd.Watch(context.Background(), fmt.Sprintf("/%s/", common.GlobalConf.AccountConf.Name), clientv3.WithPrefix()) |
25 | go func() { | 25 | go func() { |
26 | for wresp := range rch { | 26 | for wresp := range rch { |
27 | for _, ev := range wresp.Events { | 27 | for _, ev := range wresp.Events { |
@@ -35,7 +35,7 @@ func TestEtcdClient_GetByPrefix(t *testing.T) { | @@ -35,7 +35,7 @@ func TestEtcdClient_GetByPrefix(t *testing.T) { | ||
35 | } | 35 | } |
36 | }() | 36 | }() |
37 | 37 | ||
38 | - game := etcd.etcd.Watch(context.Background(), fmt.Sprintf("/%s/", conf.GlobalConf.GameConf.Name), clientv3.WithPrefix()) | 38 | + game := etcd.etcd.Watch(context.Background(), fmt.Sprintf("/%s/", common.GlobalConf.GameConf.Name), clientv3.WithPrefix()) |
39 | for wresp := range game { | 39 | for wresp := range game { |
40 | for _, ev := range wresp.Events { | 40 | for _, ev := range wresp.Events { |
41 | switch ev.Type { | 41 | switch ev.Type { |
utils/logger/README.md renamed to common/logger/README.md
utils/logger/conn.go renamed to common/logger/conn.go
utils/logger/console.go renamed to common/logger/console.go
utils/logger/file.go renamed to common/logger/file.go
utils/logger/log.go renamed to common/logger/log.go
utils/snowflake.go renamed to common/snowflake.go
conf/conf.yaml
@@ -21,17 +21,22 @@ server_account: | @@ -21,17 +21,22 @@ server_account: | ||
21 | name: "account" | 21 | name: "account" |
22 | ip: "192.168.0.206" | 22 | ip: "192.168.0.206" |
23 | port: 8858 | 23 | port: 8858 |
24 | - dbname: "account" | ||
25 | pool_size: 1 | 24 | pool_size: 1 |
25 | + debugport: 6061 | ||
26 | + mongo: | ||
27 | + <<: *default-mongo | ||
28 | + dbname: "account" | ||
26 | 29 | ||
27 | server_game: | 30 | server_game: |
28 | id: "1" | 31 | id: "1" |
29 | name: "game" | 32 | name: "game" |
30 | ip: "192.168.0.206" | 33 | ip: "192.168.0.206" |
31 | port: 8850 | 34 | port: 8850 |
32 | - dbname: "game" | ||
33 | pool_size: 1 | 35 | pool_size: 1 |
34 | plugin_path: "./bin/plugin.so" | 36 | plugin_path: "./bin/plugin.so" |
37 | + mongo: | ||
38 | + <<: *default-mongo | ||
39 | + dbname: "game" | ||
35 | 40 | ||
36 | logconf: | 41 | logconf: |
37 | TimeFormat: "2006-01-02 15:04:05" | 42 | TimeFormat: "2006-01-02 15:04:05" |
models/account.go
@@ -2,11 +2,10 @@ package models | @@ -2,11 +2,10 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "pro2d/pb" | 4 | "pro2d/pb" |
5 | - "pro2d/utils/db" | ||
6 | ) | 5 | ) |
7 | 6 | ||
8 | type AccountModel struct { | 7 | type AccountModel struct { |
9 | - *db.Schema | 8 | + *Schema |
10 | *pb.Account | 9 | *pb.Account |
11 | } | 10 | } |
12 | 11 | ||
@@ -21,9 +20,11 @@ func AccountExistByPhone(phone string) (bool, *AccountModel){ | @@ -21,9 +20,11 @@ func AccountExistByPhone(phone string) (bool, *AccountModel){ | ||
21 | func NewAccount(phone string) *AccountModel { | 20 | func NewAccount(phone string) *AccountModel { |
22 | ac := &pb.Account{ | 21 | ac := &pb.Account{ |
23 | Phone: phone, | 22 | Phone: phone, |
23 | + | ||
24 | } | 24 | } |
25 | + | ||
25 | account := &AccountModel{ | 26 | account := &AccountModel{ |
26 | - Schema: db.NewSchema(phone, ac), | 27 | + Schema: NewSchema(phone, ac), |
27 | Account: ac, | 28 | Account: ac, |
28 | } | 29 | } |
29 | 30 |
models/equip.go
@@ -2,20 +2,19 @@ package models | @@ -2,20 +2,19 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "pro2d/pb" | 4 | "pro2d/pb" |
5 | - "pro2d/utils/db" | ||
6 | ) | 5 | ) |
7 | 6 | ||
8 | -type EquipModels struct { | ||
9 | - *db.Schema | 7 | +type EquipModel struct { |
8 | + *Schema | ||
10 | Equip *pb.Equipment | 9 | Equip *pb.Equipment |
11 | } | 10 | } |
12 | 11 | ||
13 | -func NewEquip(id string) *EquipModels { | 12 | +func NewEquip(id string) *EquipModel { |
14 | data := &pb.Equipment{ | 13 | data := &pb.Equipment{ |
15 | Id: id, | 14 | Id: id, |
16 | } | 15 | } |
17 | - m := &EquipModels{ | ||
18 | - Schema: db.NewSchema(id, data), | 16 | + m := &EquipModel{ |
17 | + Schema: NewSchema(id, data), | ||
19 | Equip: data, | 18 | Equip: data, |
20 | } | 19 | } |
21 | 20 |
models/hero.go
@@ -2,11 +2,10 @@ package models | @@ -2,11 +2,10 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "pro2d/pb" | 4 | "pro2d/pb" |
5 | - "pro2d/utils/db" | ||
6 | ) | 5 | ) |
7 | 6 | ||
8 | type HeroModel struct { | 7 | type HeroModel struct { |
9 | - *db.Schema | 8 | + *Schema |
10 | Hero *pb.Hero | 9 | Hero *pb.Hero |
11 | } | 10 | } |
12 | type HeroMap map[string]*HeroModel | 11 | type HeroMap map[string]*HeroModel |
@@ -24,7 +23,7 @@ func NewHero(id string) *HeroModel { | @@ -24,7 +23,7 @@ func NewHero(id string) *HeroModel { | ||
24 | Id: id, | 23 | Id: id, |
25 | } | 24 | } |
26 | m := &HeroModel{ | 25 | m := &HeroModel{ |
27 | - Schema: db.NewSchema(id, h), | 26 | + Schema: NewSchema(id, h), |
28 | Hero: h, | 27 | Hero: h, |
29 | } | 28 | } |
30 | return m | 29 | return m |
models/init.go
1 | package models | 1 | package models |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "pro2d/common/db" | ||
4 | "pro2d/pb" | 5 | "pro2d/pb" |
5 | - "pro2d/utils" | ||
6 | - "pro2d/utils/db" | ||
7 | - "pro2d/utils/logger" | ||
8 | ) | 6 | ) |
9 | 7 | ||
10 | -func InitDoc(schema ...interface{}) { | ||
11 | - for _, s := range schema { | ||
12 | - coll, keys := utils.FindIndex(s) | ||
13 | - for _, index := range keys { | ||
14 | - db.CreateCollection(coll) | ||
15 | - | ||
16 | - logger.Debug("InitDoc collect: %v, createIndex: %s", coll, index) | ||
17 | - res, err := db.SetUnique(coll, index) | ||
18 | - if err != nil { | ||
19 | - logger.Error("InitDoc unique: %s, err: %v", res, err) | ||
20 | - continue | ||
21 | - } | ||
22 | - } | ||
23 | - } | ||
24 | -} | ||
25 | - | ||
26 | -func InitAccountServerModels() { | 8 | +func InitModels() { |
27 | var schema []interface{} = []interface{}{ | 9 | var schema []interface{} = []interface{}{ |
28 | pb.Account{}, | 10 | pb.Account{}, |
29 | - } | ||
30 | - InitDoc(schema...) | ||
31 | -} | ||
32 | - | ||
33 | -func InitGameServerModels() { | ||
34 | - var schema []interface{} = []interface{}{ | 11 | + pb.Equipment{}, |
35 | pb.Hero{}, | 12 | pb.Hero{}, |
13 | + pb.Prop{}, | ||
36 | pb.Role{}, | 14 | pb.Role{}, |
37 | pb.Team{}, | 15 | pb.Team{}, |
38 | } | 16 | } |
39 | - InitDoc(schema...) | ||
40 | -} | ||
41 | \ No newline at end of file | 17 | \ No newline at end of file |
18 | + db.InitDoc(schema...) | ||
19 | +} |
models/init_test.go deleted
@@ -1,20 +0,0 @@ | @@ -1,20 +0,0 @@ | ||
1 | -package models | ||
2 | - | ||
3 | -import ( | ||
4 | - "context" | ||
5 | - _ "pro2d/conf" | ||
6 | - "pro2d/utils/db" | ||
7 | - "testing" | ||
8 | -) | ||
9 | - | ||
10 | - | ||
11 | -func TestInitModels(t *testing.T) { | ||
12 | - | ||
13 | - db.MongoDatabase = db.MongoClient.Database("account") | ||
14 | - InitAccountServerModels() | ||
15 | - db.MongoClient.Disconnect(context.TODO()) | ||
16 | - | ||
17 | - db.MongoDatabase = db.MongoClient.Database("game") | ||
18 | - InitGameServerModels() | ||
19 | - db.MongoClient.Disconnect(context.TODO()) | ||
20 | -} | ||
21 | \ No newline at end of file | 0 | \ No newline at end of file |
models/prop.go
@@ -2,20 +2,19 @@ package models | @@ -2,20 +2,19 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "pro2d/pb" | 4 | "pro2d/pb" |
5 | - "pro2d/utils/db" | ||
6 | ) | 5 | ) |
7 | 6 | ||
8 | -type PropModels struct { | ||
9 | - *db.Schema | 7 | +type PropModel struct { |
8 | + *Schema | ||
10 | Prop *pb.Prop | 9 | Prop *pb.Prop |
11 | } | 10 | } |
12 | 11 | ||
13 | -func NewProp(id string) *PropModels { | 12 | +func NewProp(id string) *PropModel { |
14 | data := &pb.Prop{ | 13 | data := &pb.Prop{ |
15 | Id: id, | 14 | Id: id, |
16 | } | 15 | } |
17 | - m := &PropModels{ | ||
18 | - Schema: db.NewSchema(id, data), | 16 | + m := &PropModel{ |
17 | + Schema: NewSchema(id, data), | ||
19 | Prop: data, | 18 | Prop: data, |
20 | } | 19 | } |
21 | 20 |
models/role.go
@@ -3,20 +3,20 @@ package models | @@ -3,20 +3,20 @@ package models | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | "pro2d/common" | 5 | "pro2d/common" |
6 | + "pro2d/common/db" | ||
7 | + "pro2d/common/logger" | ||
6 | "pro2d/pb" | 8 | "pro2d/pb" |
7 | "pro2d/utils" | 9 | "pro2d/utils" |
8 | - "pro2d/utils/db" | ||
9 | - "pro2d/utils/logger" | ||
10 | "sync/atomic" | 10 | "sync/atomic" |
11 | ) | 11 | ) |
12 | 12 | ||
13 | type RoleModel struct { | 13 | type RoleModel struct { |
14 | - *db.Schema | 14 | + *Schema |
15 | Role *pb.Role | 15 | Role *pb.Role |
16 | Heros HeroMap | 16 | Heros HeroMap |
17 | Teams *TeamModel | 17 | Teams *TeamModel |
18 | - Equip *EquipModels | ||
19 | - Prop *PropModels | 18 | + Equip *EquipModel |
19 | + Prop *PropModel | ||
20 | 20 | ||
21 | lastSaveTs int64 | 21 | lastSaveTs int64 |
22 | } | 22 | } |
@@ -31,12 +31,12 @@ func RoleExistByUid(uid string) *RoleModel { | @@ -31,12 +31,12 @@ func RoleExistByUid(uid string) *RoleModel { | ||
31 | 31 | ||
32 | 32 | ||
33 | r := &RoleModel{ | 33 | r := &RoleModel{ |
34 | - Schema: db.NewSchema(data.Id, data), | 34 | + Schema: NewSchema(data.Id, data), |
35 | Role: data, | 35 | Role: data, |
36 | Heros: make(HeroMap), | 36 | Heros: make(HeroMap), |
37 | Teams: new(TeamModel), | 37 | Teams: new(TeamModel), |
38 | - Equip: new(EquipModels), | ||
39 | - Prop: new(PropModels), | 38 | + Equip: new(EquipModel), |
39 | + Prop: new(PropModel), | ||
40 | } | 40 | } |
41 | r.LoadAll() | 41 | r.LoadAll() |
42 | return r | 42 | return r |
@@ -45,12 +45,12 @@ func RoleExistByUid(uid string) *RoleModel { | @@ -45,12 +45,12 @@ func RoleExistByUid(uid string) *RoleModel { | ||
45 | func NewRole(id string) *RoleModel { | 45 | func NewRole(id string) *RoleModel { |
46 | data := &pb.Role{Id: id} | 46 | data := &pb.Role{Id: id} |
47 | m := &RoleModel{ | 47 | m := &RoleModel{ |
48 | - Schema: db.NewSchema(id, data), | 48 | + Schema: NewSchema(id, data), |
49 | Role: data, | 49 | Role: data, |
50 | Heros: make(HeroMap), | 50 | Heros: make(HeroMap), |
51 | Teams: new(TeamModel), | 51 | Teams: new(TeamModel), |
52 | - Equip: new(EquipModels), | ||
53 | - Prop: new(PropModels), | 52 | + Equip: new(EquipModel), |
53 | + Prop: new(PropModel), | ||
54 | } | 54 | } |
55 | return m | 55 | return m |
56 | } | 56 | } |
models/role_test.go
@@ -2,16 +2,20 @@ package models | @@ -2,16 +2,20 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | - _ "pro2d/conf" | 5 | + "pro2d/common" |
6 | + "pro2d/common/db" | ||
7 | + "pro2d/common/logger" | ||
6 | "pro2d/pb" | 8 | "pro2d/pb" |
7 | "pro2d/utils" | 9 | "pro2d/utils" |
8 | - "pro2d/utils/db" | ||
9 | - "pro2d/utils/logger" | ||
10 | "testing" | 10 | "testing" |
11 | ) | 11 | ) |
12 | 12 | ||
13 | func TestNewRole(t *testing.T) { | 13 | func TestNewRole(t *testing.T) { |
14 | - db.MongoDatabase = db.MongoClient.Database("game") | 14 | + err := db.ConnectMongo(common.GlobalConf.MongoConf) |
15 | + if err != nil { | ||
16 | + logger.Error(err) | ||
17 | + return | ||
18 | + } | ||
15 | 19 | ||
16 | var uid = "141815055745814528" | 20 | var uid = "141815055745814528" |
17 | role := RoleExistByUid(uid) | 21 | role := RoleExistByUid(uid) |
utils/db/schema.go renamed to models/schema.go
1 | -package db | 1 | +package models |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "pro2d/common/components" | ||
5 | + "pro2d/common/db" | ||
6 | + "pro2d/common/logger" | ||
4 | "reflect" | 7 | "reflect" |
5 | "strings" | 8 | "strings" |
6 | ) | 9 | ) |
7 | 10 | ||
11 | +type SchemaOption func(schema *Schema) | ||
12 | + | ||
13 | +func WithSchemaDB(idb components.IDB) SchemaOption { | ||
14 | + return func(schema *Schema) { | ||
15 | + schema.db = idb | ||
16 | + } | ||
17 | +} | ||
18 | + | ||
8 | type Schema struct { | 19 | type Schema struct { |
9 | - mgo *MgoColl | 20 | + db components.IDB |
10 | reflectValue *reflect.Value | 21 | reflectValue *reflect.Value |
11 | reflectType reflect.Type | 22 | reflectType reflect.Type |
12 | 23 | ||
@@ -27,28 +38,42 @@ func NewSchema(key string, schema interface{}) *Schema { | @@ -27,28 +38,42 @@ func NewSchema(key string, schema interface{}) *Schema { | ||
27 | cacheFields: make(map[string]interface{}), | 38 | cacheFields: make(map[string]interface{}), |
28 | schema: schema, | 39 | schema: schema, |
29 | } | 40 | } |
30 | - sch.mgo = NewMongoColl(sch) | ||
31 | - sch.pri = GetBsonD(sch.getPriTag(), key) | 41 | + |
42 | + sch.db = db.NewMongoColl(sch.GetSchemaName(), sch) | ||
43 | + sch.pri = db.GetBsonD(sch.getPriTag(), key) | ||
32 | return sch | 44 | return sch |
33 | } | 45 | } |
34 | 46 | ||
35 | -func (s *Schema) GetSchemaType() reflect.Type { | ||
36 | - return s.reflectType | 47 | +func (s *Schema) FindIndex() (string, []string) { |
48 | + var index []string | ||
49 | + for i := 0; i < s.reflectType.NumField(); i++ { | ||
50 | + if s.reflectType.Field(i).Tag.Get("index") != "" { | ||
51 | + js := strings.Split(s.reflectType.Field(i).Tag.Get("json"), ",") | ||
52 | + if len(js) == 0 { | ||
53 | + continue | ||
54 | + } | ||
55 | + index = append(index, js[0]) | ||
56 | + } | ||
57 | + } | ||
58 | + return strings.ToLower(s.reflectType.Name()), index | ||
37 | } | 59 | } |
38 | 60 | ||
39 | -func (s *Schema) GetCollName() string { | ||
40 | - return strings.ToLower(s.GetSchemaType().Name()) | ||
41 | -} | 61 | +func (s *Schema) Init() { |
62 | + coll, keys := s.FindIndex() | ||
63 | + for _, index := range keys { | ||
64 | + s.db.CreateTable() | ||
42 | 65 | ||
43 | -func (s *Schema) getPriTag() string { | ||
44 | - var pri string | ||
45 | - for i := 0; i < s.reflectType.NumField(); i++ { | ||
46 | - if s.reflectType.Field(i).Tag.Get("pri") == "1" { | ||
47 | - pri = strings.ToLower(s.reflectType.Field(i).Name) | ||
48 | - break | 66 | + logger.Debug("InitDoc collect: %v, createIndex: %s", coll, index) |
67 | + res, err := s.db.SetUnique(index) | ||
68 | + if err != nil { | ||
69 | + logger.Error("InitDoc unique: %s, err: %v", res, err) | ||
70 | + continue | ||
49 | } | 71 | } |
50 | } | 72 | } |
51 | - return pri | 73 | +} |
74 | + | ||
75 | +func (s *Schema) GetDB() components.IDB { | ||
76 | + return s.db | ||
52 | } | 77 | } |
53 | 78 | ||
54 | func (s *Schema) GetPri() interface{} { | 79 | func (s *Schema) GetPri() interface{} { |
@@ -59,18 +84,22 @@ func (s *Schema) GetSchema() interface{} { | @@ -59,18 +84,22 @@ func (s *Schema) GetSchema() interface{} { | ||
59 | return s.schema | 84 | return s.schema |
60 | } | 85 | } |
61 | 86 | ||
87 | +func (s *Schema) GetSchemaName() string { | ||
88 | + return strings.ToLower(s.reflectType.Name()) | ||
89 | +} | ||
90 | + | ||
62 | func (s *Schema) Load() error { | 91 | func (s *Schema) Load() error { |
63 | - return s.mgo.Load() | 92 | + return s.db.Load() |
64 | } | 93 | } |
65 | 94 | ||
66 | func (s *Schema) Create() error { | 95 | func (s *Schema) Create() error { |
67 | - _, err := s.mgo.Create() | 96 | + _, err := s.db.Create() |
68 | return err | 97 | return err |
69 | } | 98 | } |
70 | 99 | ||
71 | func (s *Schema) Update() { | 100 | func (s *Schema) Update() { |
72 | if s.cacheFields != nil { | 101 | if s.cacheFields != nil { |
73 | - s.mgo.UpdateProperties(s.cacheFields) | 102 | + s.db.UpdateProperties(s.cacheFields) |
74 | s.cacheFields = make(map[string]interface{}) | 103 | s.cacheFields = make(map[string]interface{}) |
75 | } | 104 | } |
76 | } | 105 | } |
@@ -85,4 +114,15 @@ func (s *Schema) SetProperties(properties map[string]interface{}) { | @@ -85,4 +114,15 @@ func (s *Schema) SetProperties(properties map[string]interface{}) { | ||
85 | s.reflectValue.FieldByName(key).Set(reflect.ValueOf(val)) | 114 | s.reflectValue.FieldByName(key).Set(reflect.ValueOf(val)) |
86 | s.cacheFields[strings.ToLower(key)] = val | 115 | s.cacheFields[strings.ToLower(key)] = val |
87 | } | 116 | } |
88 | -} | ||
89 | \ No newline at end of file | 117 | \ No newline at end of file |
118 | +} | ||
119 | + | ||
120 | +func (s *Schema) getPriTag() string { | ||
121 | + var pri string | ||
122 | + for i := 0; i < s.reflectType.NumField(); i++ { | ||
123 | + if s.reflectType.Field(i).Tag.Get("pri") == "1" { | ||
124 | + pri = strings.ToLower(s.reflectType.Field(i).Name) | ||
125 | + break | ||
126 | + } | ||
127 | + } | ||
128 | + return pri | ||
129 | +} |
models/team.go
@@ -2,11 +2,10 @@ package models | @@ -2,11 +2,10 @@ package models | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "pro2d/pb" | 4 | "pro2d/pb" |
5 | - "pro2d/utils/db" | ||
6 | ) | 5 | ) |
7 | 6 | ||
8 | type TeamModel struct { | 7 | type TeamModel struct { |
9 | - *db.Schema | 8 | + *Schema |
10 | Team *pb.Team | 9 | Team *pb.Team |
11 | } | 10 | } |
12 | 11 | ||
@@ -15,7 +14,7 @@ func NewTeam(id string) *TeamModel { | @@ -15,7 +14,7 @@ func NewTeam(id string) *TeamModel { | ||
15 | Id: id, | 14 | Id: id, |
16 | } | 15 | } |
17 | m := &TeamModel{ | 16 | m := &TeamModel{ |
18 | - Schema: db.NewSchema(id, data), | 17 | + Schema: NewSchema(id, data), |
19 | Team: data, | 18 | Team: data, |
20 | } | 19 | } |
21 | 20 |
utils/db/mongo.go deleted
@@ -1,224 +0,0 @@ | @@ -1,224 +0,0 @@ | ||
1 | -package db | ||
2 | - | ||
3 | -import ( | ||
4 | - "context" | ||
5 | - "fmt" | ||
6 | - "go.mongodb.org/mongo-driver/bson" | ||
7 | - "go.mongodb.org/mongo-driver/mongo" | ||
8 | - "go.mongodb.org/mongo-driver/mongo/options" | ||
9 | - "go.mongodb.org/mongo-driver/mongo/readpref" | ||
10 | - "go.mongodb.org/mongo-driver/x/bsonx" | ||
11 | - "pro2d/utils" | ||
12 | - "sort" | ||
13 | - "strconv" | ||
14 | - "strings" | ||
15 | - "time" | ||
16 | -) | ||
17 | - | ||
18 | -var ( | ||
19 | - MongoClient *mongo.Client | ||
20 | - MongoDatabase *mongo.Database | ||
21 | -) | ||
22 | - | ||
23 | -//初始化 | ||
24 | -func Connect(user, password, host string,port int, MaxNum int, timeOut int) error { | ||
25 | - var uri string | ||
26 | - if user!= "" { | ||
27 | - //uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?w=majority", conf.User, conf.Password, conf.Host, conf.Port, conf.DBName) | ||
28 | - uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/?w=majority", user, password, host, port) | ||
29 | - }else { | ||
30 | - //uri = fmt.Sprintf("mongodb://%s:%d/%s?w=majority", conf.Host, conf.Port, conf.DBName) | ||
31 | - uri = fmt.Sprintf("mongodb://%s:%d/?w=majority", host, port) | ||
32 | - } | ||
33 | - // 设置连接超时时间 | ||
34 | - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeOut)) | ||
35 | - defer cancel() | ||
36 | - // 通过传进来的uri连接相关的配置 | ||
37 | - o := options.Client().ApplyURI(uri) | ||
38 | - // 设置最大连接数 - 默认是100 ,不设置就是最大 max 64 | ||
39 | - o.SetMaxPoolSize(uint64(MaxNum)) | ||
40 | - // 发起链接 | ||
41 | - var err error | ||
42 | - MongoClient, err = mongo.Connect(ctx, o) | ||
43 | - if err != nil { | ||
44 | - return err | ||
45 | - } | ||
46 | - // 判断服务是不是可用 | ||
47 | - if err = MongoClient.Ping(context.Background(), readpref.Primary()); err != nil { | ||
48 | - return err | ||
49 | - } | ||
50 | - | ||
51 | - //MongoDatabase = MongoClient.Database(dbname) | ||
52 | - return nil | ||
53 | -} | ||
54 | - | ||
55 | -func CreateCollection(collection string) error { | ||
56 | - colls, _ := MongoDatabase.ListCollectionNames(context.TODO(), bson.D{}) | ||
57 | - pos := sort.SearchStrings(colls, collection) | ||
58 | - if pos != len(colls) { | ||
59 | - if collection == colls[pos] { | ||
60 | - return MongoDatabase.CreateCollection(context.TODO(), collection) | ||
61 | - } | ||
62 | - } | ||
63 | - return MongoDatabase.CreateCollection(context.TODO(), collection) | ||
64 | -} | ||
65 | - | ||
66 | -func SetUnique(collection string, key string) (string, error) { | ||
67 | - return MongoDatabase.Collection(collection).Indexes().CreateOne( | ||
68 | - context.TODO(), | ||
69 | - mongo.IndexModel{ | ||
70 | - Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, | ||
71 | - Options: options.Index().SetUnique(true), | ||
72 | - }, | ||
73 | - ) | ||
74 | -} | ||
75 | - | ||
76 | -type MgoColl struct { | ||
77 | - collection *mongo.Collection | ||
78 | - | ||
79 | - schema *Schema | ||
80 | -} | ||
81 | - | ||
82 | -func GetBsonD(key string, value interface{}) interface{} { | ||
83 | - return bson.D{ {key, value}} | ||
84 | -} | ||
85 | -func GetBsonM(key string, value interface{}) interface{} { | ||
86 | - return bson.M{key: value} | ||
87 | -} | ||
88 | - | ||
89 | -func NewMongoColl(schema *Schema) *MgoColl { | ||
90 | - return &MgoColl{ | ||
91 | - collection: MongoDatabase.Collection(schema.GetCollName()), | ||
92 | - schema: schema, | ||
93 | - } | ||
94 | -} | ||
95 | - | ||
96 | -func FindOne(pri interface{}, schema interface{}) error { | ||
97 | - r := MongoDatabase.Collection(utils.GetCollName(schema)).FindOne(context.TODO(), pri) | ||
98 | - return r.Decode(schema) | ||
99 | -} | ||
100 | - | ||
101 | -// 查询单个 | ||
102 | -func (m *MgoColl) FindOneKV(key string, value interface{}) *mongo.SingleResult { | ||
103 | - //collection. | ||
104 | - filter := bson.D{ {key, value}} | ||
105 | - singleResult := m.collection.FindOne(context.TODO(), filter) | ||
106 | - return singleResult | ||
107 | -} | ||
108 | - | ||
109 | -//查询集合里有多少数据 | ||
110 | -func (m *MgoColl) CollectionCount() (string, int64) { | ||
111 | - size, _ := m.collection.EstimatedDocumentCount(context.TODO()) | ||
112 | - return m.collection.Name(), size | ||
113 | -} | ||
114 | - | ||
115 | -//按选项查询集合 Skip 跳过 Limit 读取数量 sort 1 ,-1 . 1 为最初时间读取 , -1 为最新时间读取 | ||
116 | -func (m *MgoColl) CollectionDocuments(Skip, Limit int64, sort int) *mongo.Cursor { | ||
117 | - SORT := bson.D{ | ||
118 | - {"_id", sort}} //filter := bson.D{ {key,value}} | ||
119 | - filter := bson.D{ | ||
120 | - {}} | ||
121 | - findOptions := options.Find().SetSort(SORT).SetLimit(Limit).SetSkip(Skip) | ||
122 | - //findOptions.SetLimit(i) | ||
123 | - temp, _ := m.collection.Find(context.Background(), filter, findOptions) | ||
124 | - return temp | ||
125 | -} | ||
126 | - | ||
127 | -//获取集合创建时间和编号 | ||
128 | -func (m *MgoColl) ParsingId(result string) (time.Time, uint64) { | ||
129 | - temp1 := result[:8] | ||
130 | - timestamp, _ := strconv.ParseInt(temp1, 16, 64) | ||
131 | - dateTime := time.Unix(timestamp, 0) //这是截获情报时间 时间格式 2019-04-24 09:23:39 +0800 CST | ||
132 | - temp2 := result[18:] | ||
133 | - count, _ := strconv.ParseUint(temp2, 16, 64) //截获情报的编号 | ||
134 | - return dateTime, count | ||
135 | -} | ||
136 | - | ||
137 | -//删除文章和查询文章 | ||
138 | -func (m *MgoColl) DeleteAndFind(key string, value interface{}) (int64, *mongo.SingleResult) { | ||
139 | - filter := bson.D{ | ||
140 | - {key, value}} | ||
141 | - singleResult := m.collection.FindOne(context.TODO(), filter) | ||
142 | - DeleteResult, err := m.collection.DeleteOne(context.TODO(), filter, nil) | ||
143 | - if err != nil { | ||
144 | - fmt.Println("删除时出现错误,你删不掉的~") | ||
145 | - } | ||
146 | - return DeleteResult.DeletedCount, singleResult | ||
147 | -} | ||
148 | - | ||
149 | -//删除文章 | ||
150 | -func (m *MgoColl) Delete(key string, value interface{}) int64 { | ||
151 | - filter := bson.D{ {key, value}} | ||
152 | - count, err := m.collection.DeleteOne(context.TODO(), filter, nil) | ||
153 | - if err != nil { | ||
154 | - fmt.Println(err) | ||
155 | - } | ||
156 | - return count.DeletedCount | ||
157 | - | ||
158 | -} | ||
159 | - | ||
160 | -//删除多个 | ||
161 | -func (m *MgoColl) DeleteMany(key string, value interface{}) int64 { | ||
162 | - filter := bson.D{ {key, value}} | ||
163 | - | ||
164 | - count, err := m.collection.DeleteMany(context.TODO(), filter) | ||
165 | - if err != nil { | ||
166 | - fmt.Println(err) | ||
167 | - } | ||
168 | - return count.DeletedCount | ||
169 | -} | ||
170 | - | ||
171 | -//索引 | ||
172 | -func (m *MgoColl) SetUnique(key string){ | ||
173 | - m.collection.Indexes().CreateOne( | ||
174 | - context.Background(), | ||
175 | - mongo.IndexModel{ | ||
176 | - Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, | ||
177 | - Options: options.Index().SetUnique(true), | ||
178 | - }, | ||
179 | - ) | ||
180 | -} | ||
181 | - | ||
182 | -//更新&保存 | ||
183 | -func (m *MgoColl) FindOneAndUpdate(filter interface{}, update interface{})*mongo.SingleResult { | ||
184 | - //filter := bson.M{"name": "x", "array.name": "b"} | ||
185 | - //update := bson.M{"array.$[item].detail": "test"} | ||
186 | - | ||
187 | - res := m.collection.FindOneAndUpdate(context.Background(), | ||
188 | - filter, | ||
189 | - bson.M{"$set": update}) | ||
190 | - if res.Err() != nil { | ||
191 | - return nil | ||
192 | - } | ||
193 | - return res | ||
194 | -} | ||
195 | - | ||
196 | -func (m *MgoColl) UpdateOne(filter interface{}, update interface{})*mongo.UpdateResult { | ||
197 | - res, err := m.collection.UpdateOne(context.TODO(), filter, bson.D{{"$set", update}}) | ||
198 | - if err != nil { | ||
199 | - return nil | ||
200 | - } | ||
201 | - | ||
202 | - return res | ||
203 | -} | ||
204 | - | ||
205 | -func (m *MgoColl) Load() error{ | ||
206 | - r := m.collection.FindOne(context.TODO(), m.schema.GetPri()) | ||
207 | - err := r.Decode(m.schema.GetSchema()) | ||
208 | - if err != nil { | ||
209 | - return err | ||
210 | - } | ||
211 | - return nil | ||
212 | -} | ||
213 | - | ||
214 | -func (m *MgoColl) Create() (*mongo.InsertOneResult, error){ | ||
215 | - return m.collection.InsertOne(context.TODO(), m.schema.GetSchema()) | ||
216 | -} | ||
217 | - | ||
218 | -func (m *MgoColl) UpdateProperty(key string, val interface{}) { | ||
219 | - m.UpdateOne(m.schema.GetPri(), bson.M{strings.ToLower(key): val}) | ||
220 | -} | ||
221 | - | ||
222 | -func (m *MgoColl) UpdateProperties(properties map[string]interface{}) { | ||
223 | - m.UpdateOne(m.schema.GetPri(), properties) | ||
224 | -} |
utils/utils.go
@@ -3,52 +3,9 @@ package utils | @@ -3,52 +3,9 @@ package utils | ||
3 | import ( | 3 | import ( |
4 | "crypto/md5" | 4 | "crypto/md5" |
5 | "encoding/hex" | 5 | "encoding/hex" |
6 | - "reflect" | ||
7 | - "strings" | ||
8 | "time" | 6 | "time" |
9 | ) | 7 | ) |
10 | 8 | ||
11 | -func GetSchemaType(schema interface{}) reflect.Type { | ||
12 | - s := reflect.TypeOf(schema) | ||
13 | - if s.Kind() == reflect.Ptr { | ||
14 | - s = reflect.TypeOf(schema).Elem() | ||
15 | - } | ||
16 | - return s | ||
17 | -} | ||
18 | - | ||
19 | -func GetCollName(schema interface{}) string { | ||
20 | - return strings.ToLower(GetSchemaType(schema).Name()) | ||
21 | -} | ||
22 | - | ||
23 | -func GetPriKey(schema interface{}) string { | ||
24 | - s := GetSchemaType(schema) | ||
25 | - | ||
26 | - var pri string | ||
27 | - for i := 0; i < s.NumField(); i++ { | ||
28 | - if s.Field(i).Tag.Get("pri") == "1" { | ||
29 | - pri = strings.ToLower(s.Field(i).Name) | ||
30 | - break | ||
31 | - } | ||
32 | - } | ||
33 | - return pri | ||
34 | -} | ||
35 | - | ||
36 | -func FindIndex(schema interface{}) (string, []string){ | ||
37 | - s := GetSchemaType(schema) | ||
38 | - | ||
39 | - var index []string | ||
40 | - for i := 0; i < s.NumField(); i++ { | ||
41 | - if s.Field(i).Tag.Get("index") != "" { | ||
42 | - js := strings.Split(s.Field(i).Tag.Get("json"), ",") | ||
43 | - if len(js) == 0 { | ||
44 | - continue | ||
45 | - } | ||
46 | - index = append(index, js[0]) | ||
47 | - } | ||
48 | - } | ||
49 | - return strings.ToLower(s.Name()), index | ||
50 | -} | ||
51 | - | ||
52 | func Md5V(str string) string { | 9 | func Md5V(str string) string { |
53 | h := md5.New() | 10 | h := md5.New() |
54 | h.Write([]byte(str)) | 11 | h.Write([]byte(str)) |